erc721
Actions
Actions | Description |
---|---|
mint to address with oracle approvals | |
burn (called by user) | |
register oracle | |
unregister oracle | |
register custodian | |
unregister custodian | |
getOracle | Get oracle status by ethereum address |
getCustodian | Get custodian status by ethereum address |
getApproval | getApproval status by obtid |
tokenURI | retrieve JSON information about NFT |
setBaseURI | Change the baseURI path (custodian only) |
_baseURI | Retrieve baseURI path (used as first portion of tokenURI) |
State Variables
State variables | Description |
---|---|
custodian_count | Keeps track of the number of custodians active in the oracle. Required for consensus math |
oracle_count | Keeps track of the number of custodians active in the oracle. Required for consensus math |
uoracmapv | Incrementer used to generate unique id for unregoracle approval mapping |
roracmapv | Incrementer used to generate unique id for regoracle approval mapping |
ucustmapv | Incrementer used to generate unique id for unregcust approval mapping |
rcustmapv | Incrementer used to generate unique id for regcust approval mapping |
owner | Used to store contract owner (msg.sender) when deployed |
oraclelist | list of active oracles |
_baseURIextended | Stored baseURI |
attribute[] | Holds the domain names for each tokenID 1:1 |
Events
Events | Description |
---|---|
wrapped | Event emitted when wrap has completed. |
unwrapped | Event emitted when user has unwrapped NFT. |
custodian_registered | Event emitted when a custodian has been registered |
custodian_unregistered | Event emitted when a custodian has been unregistered |
oracle_registered | Event emitted when an oracle has been registered |
oracle_unregistered | Event emitted when an oracle has been unregistered |
Mappings
Mappings | Members | Description |
---|---|---|
Custodians | custodian | Keeps track of the custodians that registered another custodian and their activation |
Oracles | oracle | Keeps track of the custodians that registered an oracle and the oracles activation count |
Approvals | pending | Keeps track of the approvals by obtid, the number of approvals, and the details of the approval |
Modifiers
Modifiers (Perms) | Action | Description |
---|---|---|
ownerOnly | _mint | default |
onlyOracle | wrapunwrap | Only FIONFT oracle may use this function |
onlyCustodian | regoracle | Only FIONFT custodian may use this function |
Misc. Requirements
Issue | Summary | Decision |
---|---|---|
Max transaction size | Should we put a max transaction size limit on mint into the ERC721 contract. | Not needed |
ERC721 contract key | What is the status of the key used to set the contract? | Key should only be used for spinning up the contract and should be burned. |
Oracle “Admin” functions | Do we need to enable the ability for Oracles to call various contract actions such as approve, transfer, mint, etc. This can be performed in a couple of ways: 2 - The Oracles can sign the next transfer action as a multisig | Decision: We do not want any Oracle admin functions. |
Custodian “Admin” functions | Are there contract actions that should be exposed to Custodian “admin” approval?
| TBD: Are there any other contract actions that might be used for “admin” functionality? |
Unwrap fee | Is there a fee for | Yes. Unwrapping user pays the fee |
Wrap/Unwrap
wrapnft
Create FIONFT on Ethereum chain
Registering oracles
NFT is created using the
wrap
action
Implementation
New action:
wrapnft
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | address | Public address on ETH blockchain where wrapped NFT should be delivered. |
domain | Yes | string | FIO Domain being wrapped. This will be included in the NFT TokenURI |
obtid | Yes | uint256 | FIO chain transaction ID |
Example
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", "tokenURI": "https://127.0.0.1/info.json"}", "obtid": "dfe50aad8e2271f84f87b8e603776d7e7970c636bb899c8993c08e9e2d21c106" }
Processing
Request is validated per Exception handling.
Consensus required. Transaction is executed when all registered oracles have called
wrap
(submitted their “observation”).Current:
3 oracles call wrap to get it approved
Then, one of the oracles call it again to execute.
Updated:
Adam todo: Do the mint when the 3rd oracle calls
wrap
DONE
NFT is minted and transferred to
account
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid tokenURI | tokenURI is not valid. | 400 | "Invalid tokenURI" |
Invalid public address | Recipient public address is not valid | 400 | "Invalid public address" |
No authority | The signer is not a registered Oracle and does not have authority to call this function | 403 | "Only a FIONFT Oracle may call this function" |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
unwrapnft
Convert NFT (domain/address) on Ethereum chain to FIO domain/address on FIO chain.
Implementation
New action:
unwrapnft
Which FIO parameter should get passed in?
FIO Address
Less likely to be input incorrectly
Requires someone who buys NFT and then wants to unwrap it to own a FIO Address.
Devs agree that FIO Address is probably the cleanest path.
FIO Address hashed
Hash of address somewhat obfuscates the recipient
FIO Pub Key
Would allow for a checksum key check in the contract (which consumes gas). Not sure if the public key checksum is worth it
Current Decision: Use FIO Address
Fees
Alice covers the fee to unwrap
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
tokenID | Yes | uint256 | TokenID to be unwrapped (will be burned on Ethereum chain, sent to 0x000000000000…) |
fio_address | Yes | String | The FIO Address where NFT should be delivered on FIO chain. |
Example
{ "fio_address": "alice@wallet", "tokenID": 123 }
Processing
Request is validated per Exception handling.
No Oracle Consensus required.
Contract burns NFT and event is emitted
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid FIO address | Recipient public address is not valid | 400 | "Invalid FIO address" |
Invalid TokenID | TokenID is not valid | 400 | "Invalid tokenID" |
No authority | The signer is not a registered Oracle and does not have authority to call this function | 403 | "Only a FIONFT Oracle may call this function" |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
oracle_fee_collected | Int | Amount of SUFs collected as Oracle fee |
Example
{ "status": "OK", "oracle_fee_collected": 2000000000 }
Oracles - register/unregister
regoracle
Register Oracle.
Registering oracles
Each Oracle is registered by custodians using
regoracle
action.
Implementation
New action:
regoracle
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
Example
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Request is validated per Exception handling.
Consensus required.
Oracles are registered by custodians. 2/3+1 of active custodians are required to complete registration of a new oracle.
A minimum of 3 oracles is required to approve a
wrap
transaction.Ethereum address is registered as a valid Oracle.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid address | Ethereum address is not valid | 400 | "Invalid address" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a FIONFT custodian may call this function" |
Already registered | The Ethereum address is already registered as an Oracle | 400 | “Already registered” |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
unregoracle
Unregister Oracle.
Implementation
New action:
unregoracle
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Oracle. |
Example
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Consensus required. Oracle is removed after 2/3+1 Custodians have called
unregoracle
with sameethaddress
.Ethereum address is removed as a valid Oracle.
A minimum of 3 oracles must be maintained. If only 3 Oracles are registered,
unregoracle
can not be called.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid oracle | Oracle is not registered | 400 | "Invalid oracle" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a FIONFT custodian may call this function" |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
Custodians - register/unregister
regcust
Register Custodian
Registering Custodians
Each Custodian is registered using
regcust
action.
Implementation
New action:
regcust
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
Example
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Request is validated per Exception handling.
Consensus required. Custodians are registered as follows:
The initial 10 custodians are set upon contract deployment by the contract owner.
Subsequently, 2/3+1 of active custodians must call
regcust
to register a new custodian.
Ethereum address is added as a valid Custodian.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid address | Ethereum address is not valid | 400 | "Invalid address" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a FIONFT custodian may call this function" |
Already registered | The Ethereum address is already registered as an Custodian | 400 | “Custodian is already registered” |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
unregcust
Unregister Custodian.
Implementation
New action: unregcust
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
account | Yes | Ethereum public address | Ethereum address owned by the Custodian. |
Example
{ "account": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" }
Processing
Request is validated per Exception handling.
Consensus required. Custodian is removed after 2/3+1 of active custodians have called
unregcust
the same Ethereum address.Ethereum address is removed as a valid Custodian.
A minimum of 7 Custodians must be maintained. If only 7 Custodians are registered,
unregcust
can not be called.A custodian can not singlehandedly unregister themselves. All changes require 2/3+1. Bug, the custodian can call
unregcust
for themselves and be counted in the 2/3+1.
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
Invalid custodian | Custodian is not registered | 400 | "Invalid custodian" |
Invalid address | Ethereum address is not valid | 400 | "Invalid address" |
No authority | The signer is not a registered Custodian and does not have authority to call this function | 403 | "Only a FIONFT custodian may call this function" |
Response body
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
Example
{ "status": "OK" }
tokenURI
Get tokenURI JSON
Implementation
New action: tokenURI
Request body
Parameter | Required | Format | Definition |
---|---|---|---|
_tokenId | Yes | Integer | TokenId of NFT |
Example
{ "_tokenId": "1" }
Processing
JSON is formed inline and returned in response
Function is overriden
Exception handling
Error condition | Trigger | Type | Error message |
---|---|---|---|
NFT tokenId does not exist | Token ID not present | 400 | No token |
Response
'data:application/json, { "name":"Domain: hard@edge", "description": "Create FIO Addresses on your custom FIO Domain.", "image": "ipfs://QmdKqei7KGp1fJCP1tkhNMdm9BwYFXzKLPsbSMSPW325sH" } '
Add Comment