Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions ERC1155/erc1155.coco
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Read the specifications for more details https://eips.ethereum.org/EIPS/eip-1155

coco MT //Multi Tokens

class TokenMetadata:
Expand Down Expand Up @@ -101,12 +103,12 @@ func persistent _transfer(from Address, to Address, id U256, amount U256):
if BalanceOf[from][id] < amount:
throw "Insufficient balance for transfer"
mutate BalanceOf <- MT.BalanceOf:
BalanceOf[from][id] -= amount
generate BalanceOf[from][id] -= amount
if !BalanceOf[to]?:
disperse BalanceOf[to] <- make(Map[U256]U256)
if !BalanceOf[to][id]?:
BalanceOf[to][id] = 0
BalanceOf[to][id] += amount
generate BalanceOf[to][id] += amount

endpoint invoke persistent safeTransferFrom(from Address, to Address, id U256, amount U256, data []Bytes):
memory isApproved = _isApprovedForAll(account: from, operator: Address(Sender))
Expand Down Expand Up @@ -140,7 +142,7 @@ endpoint invoke persistent mint(to Address, tokenId U256, amount U256, tokenURI
disperse BalanceOf[to] <- make(Map[U256]U256)
if !BalanceOf[to][tokenId]?:
BalanceOf[to][tokenId] = 0
BalanceOf[to][tokenId] += amount
generate BalanceOf[to][tokenId] += amount
TotalSupply += amount
emit TransferSingle(Address(Sender), Address(0), to, tokenId, amount)

Expand Down
30 changes: 19 additions & 11 deletions ERC721/erc721.coco
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Read the specifications for more details https://eips.ethereum.org/EIPS/eip-721

coco NFT

class TokenMetadata:
Expand Down Expand Up @@ -59,6 +61,8 @@ func readonly _isApprovedOrOwner(spender Address, tokenId U256) -> (isApproved B

endpoint invoke readonly balanceOf(owner Address) -> (Balance U256):
observe BalanceOf <- NFT.BalanceOf:
if !BalanceOf[owner]?:
throw "Owner not found in BalanceOf map"
return Balance BalanceOf[owner]

endpoint invoke readonly ownerOf(tokenId U256) -> (Owner Address):
Expand All @@ -75,17 +79,21 @@ endpoint invoke persistent approve(to Address, tokenId U256):
owner = Tokens[tokenId].owner
if to == owner:
throw "Approval to current owner"
memory isAll = OperatorApprovals[owner][Address(Sender)]
memory isAll
if !OperatorApprovals[owner][Address(Sender)]?:
throw "Token does not exist"
else:
isAll = OperatorApprovals[owner][Address(Sender)]
if Address(Sender) != owner && !isAll:
throw "Caller is not token owner or approved operator"
mutate TokenApprovals <- NFT.TokenApprovals:
TokenApprovals[tokenId] = to
generate TokenApprovals[tokenId] = to

emit Approval(owner, to, tokenId)

endpoint invoke readonly getApproved(tokenId U256) -> (Approved Address, Exists Bool):
observe Tokens, TokenApprovals <- NFT.Tokens, NFT.TokenApprovals:
if !Tokens[tokenId]?:
observe TokenApprovals <- NFT.TokenApprovals:
if !TokenApprovals[tokenId]?:
return (Approved: Address(0), Exists: false)
return (Approved: TokenApprovals[tokenId], Exists: true)

Expand All @@ -95,7 +103,7 @@ endpoint invoke persistent setApprovalForAll(operator Address, approved Bool):
mutate OperatorApprovals <- NFT.OperatorApprovals:
if !OperatorApprovals[Address(Sender)]?:
disperse OperatorApprovals[Address(Sender)] <- make(Map[Address]Bool)
OperatorApprovals[Address(Sender)][operator] = approved
generate OperatorApprovals[Address(Sender)][operator] = approved
emit ApprovalForAll(Address(Sender), operator, approved)

endpoint invoke readonly isApprovedForAll(owner Address, operator Address) -> (IsApproved Bool):
Expand All @@ -120,8 +128,8 @@ endpoint invoke persistent transferFrom(from Address, to Address, tokenId U256):

mutate Tokens, BalanceOf, TokenApprovals <- NFT.Tokens, NFT.BalanceOf, NFT.TokenApprovals:
TokenApprovals[tokenId] = Address(0)
BalanceOf[from] -= 1
BalanceOf[to] += 1
generate BalanceOf[from] -= 1
generate BalanceOf[to] += 1
Tokens[tokenId].owner = to

emit Transfer(from, to, tokenId)
Expand All @@ -142,8 +150,8 @@ endpoint invoke persistent safeTransferFrom(from Address, to Address, tokenId U2

mutate Tokens, BalanceOf, TokenApprovals <- NFT.Tokens, NFT.BalanceOf, NFT.TokenApprovals:
TokenApprovals[tokenId] = Address(0)
BalanceOf[from] -= 1
BalanceOf[to] += 1
generate BalanceOf[from] -= 1
generate BalanceOf[to] += 1
Tokens[tokenId].owner = to

emit Transfer(from, to, tokenId)
Expand All @@ -158,8 +166,8 @@ endpoint invoke persistent mint(to Address, tokenId U256, tokenURI String):

mutate Tokens, BalanceOf, TotalSupply <- NFT.Tokens, NFT.BalanceOf, NFT.TotalSupply:
disperse Tokens[tokenId] <- TokenMetadata{tokenId: tokenId, owner: to, tokenURI: tokenURI}
BalanceOf[to] += 1
TotalSupply += 1
generate BalanceOf[to] += 1
generate TotalSupply += 1

emit Transfer(Address(0), to, tokenId)

Expand Down
85 changes: 85 additions & 0 deletions ERC721/guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# NFT Contract Interaction Guide

- Start API server ``logiclab start -d ~/.coco/lab``
- ```cd ERC721/```
- ```coco lab start``` Cocolab REPL start
- ```compile NFT```
- ```get NFT``` lists alll endpoints
- ```register username```
- ```set default.sender username```

## 1. Deploy the contract with a name and symbol
```
deploy NFT.Init(name: "CryptoCocoNFT", symbol: "COCO")
```

## 2. Mint three tokens to different addresses
```
invoke NFT.mint(to: 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b, tokenId: 1, tokenURI: "https://example.com/metadata/1")
invoke NFT.mint(to: 0x2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3, tokenId: 2, tokenURI: "https://example.com/metadata/2")
invoke NFT.mint(to: 0x3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4, tokenId: 3, tokenURI: "https://example.com/metadata/3")
```

## 3. Check token ownership and balance for an address
```
invoke NFT.ownerOf(tokenId: 1)
invoke NFT.balanceOf(owner: 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b)
```

## 4. Approve another address to transfer a specific token
```
invoke NFT.approve(to: 0x4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5, tokenId: 1)
```

## 5. Check the approval status for a token
```
invoke NFT.getApproved(tokenId: 1)
```

## 6. Set approval for all tokens to an operator
```
invoke NFT.setApprovalForAll(operator: 0x5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e, approved: true)
```

## 7. Check if an address is approved for all tokens of an owner
```
invoke NFT.isApprovedForAll(owner: 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b, operator: 0x5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e)
```

## 8. Transfer a token using the regular transfer method
```
invoke NFT.transferFrom(from: 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b, to: 0x6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7, tokenId: 1)
```

## 9. Transfer a token using the safe transfer method
```
invoke NFT.safeTransferFrom(from: 0x2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3, to: 0x7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8, tokenId: 2)
```

## 10. Get the URI for a token
```
invoke NFT.tokenURI(tokenId: 1)
```

## 11. Get the contract name and symbol
```
invoke NFT.name()
invoke NFT.symbol()
```

## 12. Get the total supply of tokens
```
invoke NFT.totalSupply()
```

## 13. Get a token by its index
```
invoke NFT.tokenByIndex(index: 0)
```

## 14. Get a token of a specific owner by index
```
invoke NFT.tokenOfOwnerByIndex(owner: 0x3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4, index: 0)
```

Note: Replace the example addresses with actual addresses when using this guide. Ensure that you have the necessary permissions to perform these operations on the NFT contract.