Skip to content

Commit

Permalink
Merge pull request #11 from NFT-Lab/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
FilippoFantinato authored Jun 23, 2021
2 parents 96a30de + 927a245 commit b799860
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 137 deletions.
10 changes: 6 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<version>0.1</version>

<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>
Expand Down Expand Up @@ -39,7 +39,9 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration> <release>11</release> </configuration>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
<pluginManagement>
Expand All @@ -52,7 +54,7 @@
</plugins>
</pluginManagement>
</build>

<distributionManagement>
<repository>
<id>github</id>
Expand Down
130 changes: 51 additions & 79 deletions src/main/java/io/nfteam/nftlab/hotmoka/erc721/ERC721.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import io.takamaka.code.util.StorageMapView;
import io.takamaka.code.util.StorageTreeMap;

import java.util.function.Supplier;

public class ERC721 extends Contract implements IERC721Metadata {
private final String name;
private final String symbol;
Expand Down Expand Up @@ -36,51 +34,44 @@ public class ERC721 extends Contract implements IERC721Metadata {

// ============ Getters ============

@Override
public final @View
String name() {
@Override @View
public final String name() {
return name;
}

@Override
public final @View
String symbol() {
@Override @View
public final String symbol() {
return symbol;
}

// ============ Transfer ============

@Override
public @FromContract
void safeTransferFrom(Contract from, Contract to, UnsignedBigInteger tokenId) {
@Override @FromContract
public void safeTransferFrom(Contract from, Contract to, UnsignedBigInteger tokenId) {
safeTransferFrom(from, to, tokenId, "".getBytes());
}

@Override
public @FromContract
void transferFrom(Contract from, Contract to, UnsignedBigInteger tokenId) {
@Override @FromContract
public void transferFrom(Contract from, Contract to, UnsignedBigInteger tokenId) {
Takamaka.require(_isApprovedOrOwner(caller(), tokenId), "ERC721: transfer caller is not owner nor approved");

_transfer(from, to, tokenId);
}

@Override
public @FromContract
void safeTransferFrom(Contract from, Contract to, UnsignedBigInteger tokenId, byte[] data) {
@Override @FromContract
public void safeTransferFrom(Contract from, Contract to, UnsignedBigInteger tokenId, byte[] data) {
Takamaka.require(_isApprovedOrOwner(caller(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, data);
}

protected
void _safeTransfer(Contract from, Contract to, UnsignedBigInteger tokenId, byte[] data) {
protected void _safeTransfer(Contract from, Contract to, UnsignedBigInteger tokenId, byte[] data) {
_transfer(from, to, tokenId);
// TODO: Call to _checkOnERC721Received
}

protected void _beforeTokenTransfer(Contract from, Contract to, UnsignedBigInteger tokenId) { }

protected
void _transfer(Contract from, Contract to, UnsignedBigInteger tokenId) {
protected void _transfer(Contract from, Contract to, UnsignedBigInteger tokenId) {
Takamaka.require(ownerOf(tokenId).equals(from), "ERC721: transfer of token that is not own");
Takamaka.require(to != null, "ERC721: transfer to the zero address");

Expand All @@ -98,9 +89,8 @@ void _transfer(Contract from, Contract to, UnsignedBigInteger tokenId) {

// ============ Approvals ============

@Override
public @FromContract
void approve(Contract to, UnsignedBigInteger tokenId) {
@Override @FromContract
public void approve(Contract to, UnsignedBigInteger tokenId) {
Contract owner = ownerOf(tokenId);

Takamaka.require(!owner.equals(to), "ERC721: approval to current owner");
Expand All @@ -112,40 +102,35 @@ void approve(Contract to, UnsignedBigInteger tokenId) {
_approve(to, tokenId);
}

private
void _approve(Contract to, UnsignedBigInteger tokenId) {
private void _approve(Contract to, UnsignedBigInteger tokenId) {
tokenApprovals.put(tokenId, to);
event(new Approval(ownerOf(tokenId), to, tokenId));
}

@Override
public @FromContract
void setApprovalForAll(Contract operator, boolean _approved) {
@Override @FromContract
public void setApprovalForAll(Contract operator, boolean _approved) {
Takamaka.require(operator != caller(), "ERC721: approve to caller");

operatorApprovals
.computeIfAbsent(caller(), (Supplier<StorageMap<Contract, Boolean>>) StorageTreeMap::new)
.put(operator, _approved);
operatorApprovals.putIfAbsent(caller(), new StorageTreeMap<>());

operatorApprovals.get(caller()).put(operator, _approved);

event(new ApprovalForAll(caller(), operator, _approved));
}

@Override
public @View
Contract getApproved(UnsignedBigInteger tokenId) {
@Override @View
public Contract getApproved(UnsignedBigInteger tokenId) {
Takamaka.require(_exists(tokenId), "ERC721: approved query for nonexistent token");

return tokenApprovals.get(tokenId);
}

@Override
public final @View
boolean isApprovedForAll(Contract owner, Contract operator) {
@Override @View
public final boolean isApprovedForAll(Contract owner, Contract operator) {
return operatorApprovals.getOrDefault(owner, StorageTreeMap::new).getOrDefault(operator, false);
}

protected
boolean _isApprovedOrOwner(Contract spender, UnsignedBigInteger tokenId) {
protected boolean _isApprovedOrOwner(Contract spender, UnsignedBigInteger tokenId) {
Takamaka.require(_exists(tokenId), "ERC721: operator query for nonexistent token");
Contract owner = ownerOf(tokenId);

Expand All @@ -154,19 +139,16 @@ boolean _isApprovedOrOwner(Contract spender, UnsignedBigInteger tokenId) {

// ============ MINT ============

protected
void _safeMint(Contract to, UnsignedBigInteger tokenId) {
protected void _safeMint(Contract to, UnsignedBigInteger tokenId) {
_safeMint(to, tokenId, "".getBytes());
}

protected
void _safeMint(Contract to, UnsignedBigInteger tokenId, byte[] data) {
protected void _safeMint(Contract to, UnsignedBigInteger tokenId, byte[] data) {
_mint(to, tokenId);
// TODO: _checkOnERC721Received call
}

protected
void _mint(Contract to, UnsignedBigInteger tokenId) {
protected void _mint(Contract to, UnsignedBigInteger tokenId) {
Takamaka.require(to != null, "ERC721: mint to the zero address");
Takamaka.require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(null, to, tokenId);
Expand All @@ -179,9 +161,8 @@ void _mint(Contract to, UnsignedBigInteger tokenId) {

// ============ Token URI ============

@Override
public @View
String tokenURI(UnsignedBigInteger tokenId) {
@Override @View
public String tokenURI(UnsignedBigInteger tokenId) {
Takamaka.require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

String baseURI = _baseURI();
Expand All @@ -190,26 +171,24 @@ String tokenURI(UnsignedBigInteger tokenId) {
: "";
}

protected @View
String _baseURI() {
@View
protected String _baseURI() {
return "";
}

// ============ Balance of ============

@Override
public @View
UnsignedBigInteger balanceOf(Contract owner) {
@Override @View
public UnsignedBigInteger balanceOf(Contract owner) {
Takamaka.require(owner != null, "ERC721: balance query for the zero address");

return balances.getOrDefault(owner, ZERO);
}

// ============ Owner of ============

@Override
public @View
Contract ownerOf(UnsignedBigInteger tokenId) {
@Override @View
public Contract ownerOf(UnsignedBigInteger tokenId) {
Contract owner = owners.get(tokenId);

Takamaka.require(owner != null, "ERC721: owner query for nonexistent token");
Expand All @@ -226,52 +205,46 @@ protected class ERC721Snapshot extends Storage implements IERC721View {
private final StorageMapView<UnsignedBigInteger, Contract> tokenApprovals = ERC721.this.tokenApprovals.snapshot();
private final StorageMapView<Contract, StorageMap<Contract, Boolean>> operatorApprovals = ERC721.this.operatorApprovals.snapshot();

@Override
public @View
UnsignedBigInteger balanceOf(Contract owner) {
@Override @View
public UnsignedBigInteger balanceOf(Contract owner) {
return balances.getOrDefault(owner, ZERO);
}

@Override
public @View
Contract ownerOf(UnsignedBigInteger tokenId) {
@Override @View
public Contract ownerOf(UnsignedBigInteger tokenId) {
Contract owner = owners.get(tokenId);

Takamaka.require(owner != null, "ERC721: owner query for nonexistent token");

return owner;
}

@Override
public @View
Contract getApproved(UnsignedBigInteger tokenId) {
@Override @View
public Contract getApproved(UnsignedBigInteger tokenId) {
Takamaka.require(_exists(tokenId), "ERC721: approved query for nonexistent token");

return tokenApprovals.get(tokenId);
}

@Override
public @View
boolean isApprovedForAll(Contract owner, Contract operator) {
@Override @View
public boolean isApprovedForAll(Contract owner, Contract operator) {
return operatorApprovals.getOrDefault(owner, StorageTreeMap::new).getOrDefault(operator, false);
}

@Override
public @View
IERC721View snapshot() {
@Override @View
public IERC721View snapshot() {
return this;
}
}

@Override
@Override @View
public IERC721View snapshot() {
return new ERC721Snapshot();
}

// ============ Burn ============

protected
void _burn(UnsignedBigInteger tokenId) {
protected void _burn(UnsignedBigInteger tokenId) {
Contract owner = ownerOf(tokenId);

_beforeTokenTransfer(owner, null, tokenId);
Expand All @@ -287,8 +260,8 @@ void _burn(UnsignedBigInteger tokenId) {

// ============ Exists ============

protected final @View
boolean _exists(UnsignedBigInteger tokenId) {
@View
protected final boolean _exists(UnsignedBigInteger tokenId) {
return owners.get(tokenId) != null;
}

Expand All @@ -299,8 +272,7 @@ boolean _exists(UnsignedBigInteger tokenId) {
*
* @param event the event to generate
*/
protected final
void event(Event event) {
protected final void event(Event event) {
if (generateEvents) {
Takamaka.event(event);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ public interface IERC721View {
@View
boolean isApprovedForAll(Contract owner, Contract operator);

@View
IERC721View snapshot();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@

abstract public class ERC721Burnable extends ERC721
{
public
ERC721Burnable(String name, String symbol) {
public ERC721Burnable(String name, String symbol) {
super(name, symbol);
}

public
ERC721Burnable(String name, String symbol, boolean generateEvents) {
public ERC721Burnable(String name, String symbol, boolean generateEvents) {
super(name, symbol, generateEvents);
}

Expand All @@ -24,8 +22,8 @@ abstract public class ERC721Burnable extends ERC721
*
* - The caller must own (@code tokenId) or be an approved operator.
*/
public @FromContract
void burn(UnsignedBigInteger tokenId) {
@FromContract
public void burn(UnsignedBigInteger tokenId) {
Takamaka.require(_isApprovedOrOwner(caller(), tokenId), "ERC721Burnable: caller is not owner nor approved");

_burn(tokenId);
Expand Down
Loading

0 comments on commit b799860

Please sign in to comment.