Skip to content

Commit

Permalink
update dependencies and use example token instead of flow token (#20)
Browse files Browse the repository at this point in the history
* updating dependencies and using example token instead of flow token

* updating dependencies

* fixing README and example transactions

* using better string templating

* go mod tidy

* make generate contracts
  • Loading branch information
joshuahannan authored Jun 3, 2020
1 parent 0e8024a commit 13a3da6
Show file tree
Hide file tree
Showing 19 changed files with 634 additions and 633 deletions.
33 changes: 20 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@ The feedback we are looking for is:

## Basics of the Standard:

The code for the standard is in `src/contracts/FungibleToken.cdc`. An example implementation of the standard that simulates what a simple FlowToken would be like is in `src/contracts/FlowToken.cdc`.
The code for the standard is in `src/contracts/FungibleToken.cdc`. An example implementation of the standard that simulates what a simple token would be like is in `src/contracts/ExampleToken.cdc`.

The exact smart contract that is used for the official Flow Network Token is in `src/contracts/FlowToken.cdc`

Example transactions that users could use to interact with fungible tokens are located in the `src/transactions/` directory.
Go transaction templates are in the `test/templates.go` file. These templates are mostly generic and can be used with any fungible token implementation by providing the correct addresses, names, and values.

The standard consists of a contract interface called `FungibleToken` that requires implementing contracts to define a `Vault` resource that represents the tokens that an account owns. Each account that owns tokens will have a `Vault` stored in its account storage. Users call functions on each other's `Vault`s to send and receive tokens.

Expand All @@ -60,7 +63,7 @@ Right now we are using unsigned 64-bit fixed point numbers `UFix64` as the type
- `pub var totalSupply: UFix64`
- The only required field of the contract. It would be incremented when new tokens are minted and decremented when they are destroyed.
- Event that gets emitted when the contract is initialized
- `pub event FungibleTokenInitialized(initialSupply: UFix64)`
- `pub event TokensInitialized(initialSupply: UFix64)`

2- Retrieving the token fields of a `Vault` in an account that owns tokens.

Expand All @@ -71,7 +74,7 @@ Right now we are using unsigned 64-bit fixed point numbers `UFix64` as the type
3- Withdrawing a specific amount of tokens *amount* using the *withdraw* function of the owner's `Vault`

- Provider interface
- `pub fun withdraw(amount: UFix64): @Vault`
- `pub fun withdraw(amount: UFix64): @FungibleToken.Vault`
- Conditions
- the returned Vault's balance must equal the amount withdrawn
- The amount withdrawn must be less than or equal to the balance
Expand All @@ -81,29 +84,33 @@ Right now we are using unsigned 64-bit fixed point numbers `UFix64` as the type
- Indicates how much was withdrawn and from what account the `Vault` is stored in.
If the `Vault` is not in account storage when the event is emitted,
`from` will be `nil`.
- `pub event withdraw(amount: UFix64, from: Address?)`
- `pub event TokensWithdrawn(amount: UFix64, from: Address?)`

4 - Depositing a specific amount of tokens *from* using the *deposit* function of the recipient's `Vault`

- `Receiver` interface
- `pub fun deposit(from: @Vault)`
- `pub fun deposit(from: @FungibleToken.Vault)`
- Conditions
- `from` balance must be non-zero
- The resulting balance must be equal to the initial balance + the balance of `from`
- deposit event
- Indicates how much was deposited and to what account the `Vault` is stored in.
If the `Vault` is not in account storage when the event is emitted,
`to` will be `nil`.
- `pub event Deposit(amount: UFix64, to: Address?)`
- Users could create custom `Receiver`s to trigger special code when transfers to them happen.
- `pub event TokensDeposited(amount: UFix64, to: Address?)`
- Users could create custom `Receiver`s to trigger special code when transfers to them happen, like forwarding the tokens
to another account, splitting them up, and much more.

- **ATTENTION**: It is VITALLY important that if you are making your own implementation of the fungible token interface that
you cast the input to `deposit` as the type of your token.
`let vault <- from as! @ExampleToken.Vault`
Because the interface specifies the argument as `@FungibleToken.Vault`, any resource that satisfies this can be sent to the deposit function. If you do not cast it as the type of your token, others could deposit different tokens into your Vault maliciously to change the balance.

5 - Creating an empty Vault resource

- `pub fun createEmptyVault(): @Vault`
- Currently have no event
- Defined in the contract, but not in the `Vault` resource.
This means that to create an empty `Vault`,
the caller would always have to call the function in the contract.
- `pub fun createEmptyVault(): @FungibleToken.Vault`
- Defined in the contract
To create an empty `Vault`, the caller calls the function in the contract and stores the Vault in their storage.
- Conditions:
- the balance of the returned Vault must be 0

Expand Down Expand Up @@ -173,7 +180,7 @@ A standard for token metadata is still an unsolved problem in the general blockc
To use the Flow Token contract as is, you need to follow these steps:

1. Deploy the `FungibleToken` definition to account `0x02`
2. Deploy the `FlowToken` definition to account `0x03`
2. Deploy the `ExampleToken` definition to account `0x03`
3. You can use the `get_balance.cdc` or `get_supply.cdc` scripts to read the
balance of a user's `Vault` or the total supply of all tokens, respectively.
4. Use the `setupAccount.cdc` on any account to set up the account to be able to
Expand Down
32 changes: 32 additions & 0 deletions contracts/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
const (
fungibleTokenFilename = "FungibleToken.cdc"
flowTokenFilename = "FlowToken.cdc"
exampleTokenFilename = "ExampleToken.cdc"
defaultFungibleTokenAddress = "02"
tokenForwardingFilename = "TokenForwarding.cdc"
)

// FungibleToken returns the FungibleToken contract interface.
Expand All @@ -33,3 +35,33 @@ func FlowToken(fungibleTokenAddr string) []byte {

return []byte(code)
}

// ExampleToken returns the ExampleToken contract.
//
// The returned contract will import the FungibleToken contract from the specified address.
func ExampleToken(fungibleTokenAddr string) []byte {
code := assets.MustAssetString(exampleTokenFilename)

code = strings.ReplaceAll(
code,
"0x"+defaultFungibleTokenAddress,
"0x"+fungibleTokenAddr,
)

return []byte(code)
}

// TokenForwarding returns the TokenForwarding contract.
//
// The returned contract will import the FungibleToken contract from the specified address.
func TokenForwarding(fungibleTokenAddr string) []byte {
code := assets.MustAssetString(tokenForwardingFilename)

code = strings.ReplaceAll(
code,
"0x"+defaultFungibleTokenAddress,
"0x"+fungibleTokenAddr,
)

return []byte(code)
}
12 changes: 12 additions & 0 deletions contracts/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,15 @@ func TestFlowTokenContract(t *testing.T) {
assert.NotNil(t, contract)
assert.Contains(t, string(contract), addrA.Hex())
}

func TestExampleTokenContract(t *testing.T) {
contract := contracts.ExampleToken(addrA.Hex())
assert.NotNil(t, contract)
assert.Contains(t, string(contract), addrA.Hex())
}

func TestTokenForwardingContract(t *testing.T) {
contract := contracts.TokenForwarding(addrA.Hex())
assert.NotNil(t, contract)
assert.Contains(t, string(contract), addrA.Hex())
}
10 changes: 9 additions & 1 deletion contracts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ module github.com/onflow/flow-ft/contracts
go 1.14

require (
github.com/ethereum/go-ethereum v1.9.13 // indirect
github.com/kevinburke/go-bindata v3.21.0+incompatible // indirect
github.com/onflow/flow-go-sdk v0.3.0-beta1
github.com/onflow/cadence v0.4.0 // indirect
github.com/onflow/flow-go-sdk v0.4.0
github.com/pkg/errors v0.9.1 // indirect
github.com/stretchr/testify v1.5.1
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 // indirect
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 // indirect
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect
golang.org/x/tools v0.0.0-20200323144430-8dcfad9e016e // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)
Loading

0 comments on commit 13a3da6

Please sign in to comment.