From ab10242a2b2a9e979447859f731c634594984b30 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 14:04:47 +0200 Subject: [PATCH 01/51] created some files --- example/zrc5/auth_operator.js | 51 ++ example/zrc5/burn.js | 56 ++ example/zrc5/decrease_allowance.js | 56 ++ example/zrc5/deploy.js | 100 ++++ example/zrc5/increase_allowance.js | 56 ++ example/zrc5/is_operator_for.js | 56 ++ example/zrc5/mint.js | 56 ++ example/zrc5/operator_send.js | 61 ++ example/zrc5/package-lock.json | 839 ++++++++++++++++++++++++++++ example/zrc5/package.json | 25 + example/zrc5/revoke_operator.js | 51 ++ example/zrc5/transfer.js | 56 ++ example/zrc5/transfer_from.js | 61 ++ reference/FungibleMultiToken.scilla | 195 +++++++ 14 files changed, 1719 insertions(+) create mode 100644 example/zrc5/auth_operator.js create mode 100644 example/zrc5/burn.js create mode 100644 example/zrc5/decrease_allowance.js create mode 100644 example/zrc5/deploy.js create mode 100644 example/zrc5/increase_allowance.js create mode 100644 example/zrc5/is_operator_for.js create mode 100644 example/zrc5/mint.js create mode 100644 example/zrc5/operator_send.js create mode 100644 example/zrc5/package-lock.json create mode 100644 example/zrc5/package.json create mode 100644 example/zrc5/revoke_operator.js create mode 100644 example/zrc5/transfer.js create mode 100644 example/zrc5/transfer_from.js create mode 100644 reference/FungibleMultiToken.scilla diff --git a/example/zrc5/auth_operator.js b/example/zrc5/auth_operator.js new file mode 100644 index 000000000..8f2e9698a --- /dev/null +++ b/example/zrc5/auth_operator.js @@ -0,0 +1,51 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'AuthorizeOperator', + [ + { + vname: 'operator', + type: 'ByStr20', + value: '0xF9814DFAF5b817b6Ccd2993d94348cC77b354575', + }, + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/burn.js b/example/zrc5/burn.js new file mode 100644 index 000000000..db0975b2c --- /dev/null +++ b/example/zrc5/burn.js @@ -0,0 +1,56 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'Burn', + [ + { + vname: 'burn_account', + type: 'ByStr20', + value: `${address}`, + }, + { + vname: 'amount', + type: 'Uint128', + value: '10', + }, + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/decrease_allowance.js b/example/zrc5/decrease_allowance.js new file mode 100644 index 000000000..5a28498b9 --- /dev/null +++ b/example/zrc5/decrease_allowance.js @@ -0,0 +1,56 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'DecreaseAllowance', + [ + { + vname: 'spender', + type: 'ByStr20', + value: "0xF9814DFAF5b817b6Ccd2993d94348cC77b354575", + }, + { + vname: 'amount', + type: 'Uint128', + value: "10", + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/deploy.js b/example/zrc5/deploy.js new file mode 100644 index 000000000..513172a78 --- /dev/null +++ b/example/zrc5/deploy.js @@ -0,0 +1,100 @@ +const fs = require('fs'); +const {Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const {getAddressFromPrivateKey} = require('@zilliqa-js/crypto'); + +const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + + +async function main() { + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('2000', units.Units.Li); // Gas Price that will be used by all transactions + + console.log("start to deploy zrc2: "); + const code = fs.readFileSync("../../reference/FungibleToken-Operator.scilla").toString(); + console.log("contract code is: "); + console.log(code); + const init = [ + // this parameter is mandatory for all init arrays + { + vname: "_scilla_version", + type: "Uint32", + value: "0" + }, + { + vname: "contract_owner", + type: "ByStr20", + value: `${address}` + }, + { + vname: "name", + type: "String", + value: `USDT` + }, + { + vname: "symbol", + type: "String", + value: `USDT` + }, + { + vname: "decimals", + type: "Uint32", + value: `2` + }, + { + vname: "default_operators", + type: "List ByStr20", + value: ["0x501A70ffEAA3F31C1caccE3479e74713546BAA44", "0xBFe2445408C51CD8Ee6727541195b02c891109ee", "0x428A2aA43456FE7fd2De66E48C1fBf372eC10eAE"] + }, + { + vname: "init_supply", + type: "Uint128", + value: `100000000` + } + ]; + console.log("init json is: "); + console.log(JSON.stringify(init)); + const contract = zilliqa.contracts.new(code, init); + try { + const [deployTx, ftoken] = await contract.deployWithoutConfirm({ + version: VERSION, + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(40000) + }, false); + + if (ftoken.error) { + console.error(ftoken.error); + return; + } + // check the pending status + const pendingStatus = await zilliqa.blockchain.getPendingTxn(deployTx.id); + console.log(`Pending status is: `); + console.log(pendingStatus.result); + + // process confirm + console.log(`The transaction id is:`, deployTx.id); + console.log(`Waiting transaction be confirmed`); + const confirmedTxn = await deployTx.confirm(deployTx.id); + + // Introspect the state of the underlying transaction + console.log(`Deployment Transaction ID: ${deployTx.id}`); + + // Get the deployed contract address + console.log("The contract address is:"); + console.log(ftoken.address); + } catch (e) { + console.error(e); + } + +} + +main(); \ No newline at end of file diff --git a/example/zrc5/increase_allowance.js b/example/zrc5/increase_allowance.js new file mode 100644 index 000000000..e15849e65 --- /dev/null +++ b/example/zrc5/increase_allowance.js @@ -0,0 +1,56 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'IncreaseAllowance', + [ + { + vname: 'spender', + type: 'ByStr20', + value: "0xF9814DFAF5b817b6Ccd2993d94348cC77b354575", + }, + { + vname: 'amount', + type: 'Uint128', + value: "100", + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/is_operator_for.js b/example/zrc5/is_operator_for.js new file mode 100644 index 000000000..c2ff465e5 --- /dev/null +++ b/example/zrc5/is_operator_for.js @@ -0,0 +1,56 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'IsOperatorFor', + [ + { + vname: 'token_owner', + type: 'ByStr20', + value: `${address}`, + }, + { + vname: 'operator', + type: 'ByStr20', + value: '0x501A70ffEAA3F31C1caccE3479e74713546BAA44', + }, + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/mint.js b/example/zrc5/mint.js new file mode 100644 index 000000000..99cc0d17b --- /dev/null +++ b/example/zrc5/mint.js @@ -0,0 +1,56 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'Mint', + [ + { + vname: 'recipient', + type: 'ByStr20', + value: `${address}`, + }, + { + vname: 'amount', + type: 'Uint128', + value: '100000000', + }, + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/operator_send.js b/example/zrc5/operator_send.js new file mode 100644 index 000000000..247511c0c --- /dev/null +++ b/example/zrc5/operator_send.js @@ -0,0 +1,61 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '534b41b12c3c14e282279da256d85a9ce456e1d8cea4e2ef5c49c71e321b3eac'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'OperatorSend', + [ + { + vname: 'from', + type: 'ByStr20', + value: "0x501A70ffEAA3F31C1caccE3479e74713546BAA44", + }, + { + vname: 'to', + type: 'ByStr20', + value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", + }, + { + vname: 'amount', + type: 'Uint128', + value: '10', + }, + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/package-lock.json b/example/zrc5/package-lock.json new file mode 100644 index 000000000..8c7449496 --- /dev/null +++ b/example/zrc5/package-lock.json @@ -0,0 +1,839 @@ +{ + "name": "zrc2", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@types/bip39": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bip39/-/bip39-2.4.2.tgz", + "integrity": "sha512-Vo9lqOIRq8uoIzEVrV87ZvcIM0PN9t0K3oYZ/CS61fIYKCBdOIM7mlWzXuRvSXrDtVa1uUO2w1cdfufxTC0bzg==", + "requires": { + "@types/node": "*" + } + }, + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "requires": { + "@types/node": "*" + } + }, + "@types/hdkey": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@types/hdkey/-/hdkey-0.7.1.tgz", + "integrity": "sha512-4Kkr06hq+R8a9EzVNqXGOY2x1xA7dhY6qlp6OvaZ+IJy1BCca1Cv126RD9X7CMJoXoLo8WvAizy8gQHpqW6K0Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, + "@types/node": { + "version": "14.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.2.tgz", + "integrity": "sha512-jeYJU2kl7hL9U5xuI/BhKPZ4vqGM/OmK6whiFAXVhlstzZhVamWhDSmHyGLIp+RVyuF9/d0dqr2P85aFj4BvJg==" + }, + "@zilliqa-js/account": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@zilliqa-js/account/-/account-0.8.9.tgz", + "integrity": "sha512-bQ9sJKmszotzZ3Ha1qpzMam5VCyTa+AavtcItnl7vEVnKi9j3Iy2BmysKJhWKJF6fDeEQldJZh6egIpIanebTQ==", + "requires": { + "@types/bip39": "^2.4.0", + "@types/hdkey": "^0.7.0", + "@zilliqa-js/core": "0.8.9", + "@zilliqa-js/crypto": "0.8.9", + "@zilliqa-js/proto": "0.8.3", + "@zilliqa-js/util": "0.8.8", + "bip39": "^2.5.0", + "hdkey": "^1.1.0" + } + }, + "@zilliqa-js/blockchain": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@zilliqa-js/blockchain/-/blockchain-0.8.9.tgz", + "integrity": "sha512-T5exARCdTAQIU2/1lz4+t10Y0zcdl20Ul0QY2stot9XQkYocoFty8F8x4Hkc8ZY4OVOFbUg6+9PcBP8JBq9MAA==", + "requires": { + "@zilliqa-js/account": "0.8.9", + "@zilliqa-js/contract": "0.8.9", + "@zilliqa-js/core": "0.8.9", + "@zilliqa-js/crypto": "0.8.9", + "@zilliqa-js/util": "0.8.8", + "utility-types": "^3.4.1" + } + }, + "@zilliqa-js/contract": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@zilliqa-js/contract/-/contract-0.8.9.tgz", + "integrity": "sha512-qDk3Anx/3brhpg7OgL4npEsBiYfiAfazbFKOOuByWkM4dyTI9sUYbx1rqUkq8QlhTW6tUJNoaTil/Qc2LqNgsQ==", + "requires": { + "@zilliqa-js/account": "0.8.9", + "@zilliqa-js/blockchain": "0.8.9", + "@zilliqa-js/core": "0.8.9", + "@zilliqa-js/crypto": "0.8.9", + "@zilliqa-js/util": "0.8.8", + "hash.js": "^1.1.5", + "utility-types": "^2.1.0" + }, + "dependencies": { + "utility-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-2.1.0.tgz", + "integrity": "sha512-/nP2gqavggo6l38rtQI/CdeV+2fmBGXVvHgj9kV2MAnms3TIi77Mz9BtapPFI0+GZQCqqom0vACQ+VlTTaCovw==" + } + } + }, + "@zilliqa-js/core": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@zilliqa-js/core/-/core-0.8.9.tgz", + "integrity": "sha512-cH8XFzTL6kkjbDTG3zP8TrH0H5FEXRY/IfAW83Tf75qWa4y6X4IGvy4vZVCvzbkTlyuuFBCOmWA04YweaRfyKQ==", + "requires": { + "@zilliqa-js/crypto": "0.8.9", + "@zilliqa-js/util": "0.8.8", + "cross-fetch": "^2.2.2", + "mitt": "^1.1.3" + } + }, + "@zilliqa-js/crypto": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@zilliqa-js/crypto/-/crypto-0.8.9.tgz", + "integrity": "sha512-0BSRbqVvIisFaJNKfa4J4X7yz1dD75Q+R2e71Q5CecVj0nlSDKkvXy+/ufbl/K+KrPWfK1DnNnZz4FSlNniJfw==", + "requires": { + "@zilliqa-js/util": "0.8.8", + "aes-js": "^3.1.1", + "bsert": "^0.0.4", + "elliptic": "^6.5.0", + "hash.js": "^1.1.5", + "hmac-drbg": "^1.0.1", + "pbkdf2": "^3.0.16", + "randombytes": "^2.0.6", + "scrypt.js": "^0.3.0", + "scryptsy": "^2.1.0", + "uuid": "^3.3.2" + } + }, + "@zilliqa-js/proto": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@zilliqa-js/proto/-/proto-0.8.3.tgz", + "integrity": "sha512-VFFnDk+U2F7M1y0njy0LrIVrkSTFjSw0KoF+E6kPhp2Dz4xlLQ24lND6We4mJJDKLftKeLFJACDJBWl0CihVcA==", + "requires": { + "protobufjs": "^6.8.8" + } + }, + "@zilliqa-js/subscriptions": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@zilliqa-js/subscriptions/-/subscriptions-0.8.6.tgz", + "integrity": "sha512-Jl60dz4xw82ahfUhHKZmgj4FXkEVpmC19tTb9Qs3JeJpf7pkvW4+D44wzDOwZLHULybMy6rY80VD4WhCa8qneg==", + "requires": { + "@zilliqa-js/core": "0.8.3", + "mock-socket": "^9.0.2", + "websocket": "^1.0.28" + }, + "dependencies": { + "@zilliqa-js/core": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@zilliqa-js/core/-/core-0.8.3.tgz", + "integrity": "sha512-3ZvAzLg5oPx18WSxyx6xDVSNp+2IYnhhxDe3in76aKpgurjAkdxWrhQRWpKNNrGtLNiQ2yn8vMDULxJCump3NQ==", + "requires": { + "@zilliqa-js/crypto": "0.8.3", + "@zilliqa-js/util": "0.8.3", + "cross-fetch": "^2.2.2", + "mitt": "^1.1.3" + } + }, + "@zilliqa-js/crypto": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@zilliqa-js/crypto/-/crypto-0.8.3.tgz", + "integrity": "sha512-5O93xlmYr/UWtS1oA7d1mLWSY4oH7SThtGTi4G05r2pgT8Gy2/QYvff8Uhj/8TLi5/s5Qp3WmJeI+GF8rjq6og==", + "requires": { + "@zilliqa-js/util": "0.8.3", + "aes-js": "^3.1.1", + "bsert": "^0.0.4", + "elliptic": "^6.5.0", + "hash.js": "^1.1.5", + "hmac-drbg": "^1.0.1", + "pbkdf2": "^3.0.16", + "randombytes": "^2.0.6", + "scrypt.js": "^0.3.0", + "scryptsy": "^2.1.0", + "uuid": "^3.3.2" + } + }, + "@zilliqa-js/util": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@zilliqa-js/util/-/util-0.8.3.tgz", + "integrity": "sha512-adcl6eVvsHQtYFLQYeozIIxDaY/y6y1MIIq4ShDKg/cFOJS1yLWLUA5jVHxEc+y9kRreXWrQdR2kAn1URhxdJA==", + "requires": { + "@types/bn.js": "^4.11.3", + "@types/long": "^4.0.0", + "bn.js": "^4.11.8", + "long": "^4.0.0" + } + } + } + }, + "@zilliqa-js/util": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@zilliqa-js/util/-/util-0.8.8.tgz", + "integrity": "sha512-VICSqItq2FJNqDXohThIhNOcWhsQWkNCGNaB8+2tml5yKTF8sJ3sALDqTIjt7q0AaoV0nTHndFg2q/9tJbManw==", + "requires": { + "@types/bn.js": "^4.11.3", + "@types/long": "^4.0.0", + "bn.js": "^4.11.8", + "long": "^4.0.0" + } + }, + "@zilliqa-js/zilliqa": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/@zilliqa-js/zilliqa/-/zilliqa-0.8.9.tgz", + "integrity": "sha512-42p903hdTX22qvIIzBtLxm5y1ZCmoCcwB3JAzQJP/s5y1o8QpWa1EyDx3VD1yg1chCYGmUWWysSjNRnF8V9jkw==", + "requires": { + "@zilliqa-js/account": "0.8.9", + "@zilliqa-js/blockchain": "0.8.9", + "@zilliqa-js/contract": "0.8.9", + "@zilliqa-js/core": "0.8.9", + "@zilliqa-js/crypto": "0.8.9", + "@zilliqa-js/subscriptions": "0.8.6", + "@zilliqa-js/util": "0.8.8" + } + }, + "aes-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip39": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.6.0.tgz", + "integrity": "sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==", + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "bsert": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.4.tgz", + "integrity": "sha512-VReLe1aTaHRmf80YLOHUk8ONQ48SjseZP76GlNIDheD5REYByn/Mm9yrtI0/ZCaFrcfxzgpiw1/hMMCUOSMa3w==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "bufferutil": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", + "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", + "requires": { + "node-gyp-build": "~3.7.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-fetch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", + "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==", + "requires": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + } + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" + } + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hdkey": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-1.1.2.tgz", + "integrity": "sha512-PTQ4VKu0oRnCrYfLp04iQZ7T2Cxz0UsEXYauk2j8eh6PJXCpbXuCFhOmtIFtbET0i3PMWmHN9J11gU8LEgUljQ==", + "requires": { + "bs58check": "^2.1.2", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "mitt": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", + "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==" + }, + "mock-socket": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.0.3.tgz", + "integrity": "sha512-SxIiD2yE/By79p3cNAAXyLQWTvEFNEzcAO7PH+DzRqKSFaplAPFjiQLmw8ofmpCsZf+Rhfn2/xCJagpdGmYdTw==", + "requires": { + "url-parse": "^1.4.4" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" + }, + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==" + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "protobufjs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.1.tgz", + "integrity": "sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "13.13.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.28.tgz", + "integrity": "sha512-EM/qFeRH8ZCD+TlsaIPULyyFm9vOhFIvgskY2JmHbEsWsOPgN+rtjSXrcHGgJpob4Nu17VfO95FKewr0XY7iOQ==" + } + } + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "scrypt": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", + "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", + "optional": true, + "requires": { + "nan": "^2.0.8" + } + }, + "scrypt.js": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.3.0.tgz", + "integrity": "sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A==", + "optional": true, + "requires": { + "scrypt": "^6.0.2", + "scryptsy": "^1.2.1" + }, + "dependencies": { + "scryptsy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", + "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", + "optional": true, + "requires": { + "pbkdf2": "^3.0.3" + } + } + } + }, + "scryptsy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", + "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" + }, + "secp256k1": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", + "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.5.2", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + } + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==" + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "utf-8-validate": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz", + "integrity": "sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw==", + "requires": { + "node-gyp-build": "~3.7.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utility-types": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", + "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "websocket": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.32.tgz", + "integrity": "sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==", + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + } + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + } + } +} diff --git a/example/zrc5/package.json b/example/zrc5/package.json new file mode 100644 index 000000000..bfd0c54d1 --- /dev/null +++ b/example/zrc5/package.json @@ -0,0 +1,25 @@ +{ + "name": "zrc5", + "version": "0.0.1", + "description": "Example project on how to interact with ZRC5 contract", + "main": "index.js", + "scripts": { + "deploy": "node deploy.js", + "is_operator_for": "node is_operator_for.js", + "mint": "node mint.js", + "burn": "node burn.js", + "auth_operator": "node auth_operator.js", + "operator_send": "node operator_send.js", + "revoke_operator": "node revoke_operator.js", + "increase_allowance": "node increase_allowance.js", + "decrease_allowance": "node decrease_allowance.js", + "transfer_from": "node transfer_from.js", + "transfer": "node transfer.js" + }, + "author": "vporton", + "license": "GPL-3.0", + "dependencies": { + "@zilliqa-js/zilliqa": "^0.8.9", + "tslib": "^1.10.0" + } +} diff --git a/example/zrc5/revoke_operator.js b/example/zrc5/revoke_operator.js new file mode 100644 index 000000000..ac7942097 --- /dev/null +++ b/example/zrc5/revoke_operator.js @@ -0,0 +1,51 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'RevokeOperator', + [ + { + vname: 'operator', + type: 'ByStr20', + value: '0xF9814DFAF5b817b6Ccd2993d94348cC77b354575', + }, + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/transfer.js b/example/zrc5/transfer.js new file mode 100644 index 000000000..e882ee628 --- /dev/null +++ b/example/zrc5/transfer.js @@ -0,0 +1,56 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'Transfer', + [ + { + vname: 'to', + type: 'ByStr20', + value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", + }, + { + vname: 'amount', + type: 'Uint128', + value: "100", + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/example/zrc5/transfer_from.js b/example/zrc5/transfer_from.js new file mode 100644 index 000000000..aa63c4640 --- /dev/null +++ b/example/zrc5/transfer_from.js @@ -0,0 +1,61 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '534b41b12c3c14e282279da256d85a9ce456e1d8cea4e2ef5c49c71e321b3eac'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'TransferFrom', + [ + { + vname: 'from', + type: 'ByStr20', + value: "0x501A70ffEAA3F31C1caccE3479e74713546BAA44", + }, + { + vname: 'to', + type: 'ByStr20', + value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", + }, + { + vname: 'amount', + type: 'Uint128', + value: "100", + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla new file mode 100644 index 000000000..dfb086b15 --- /dev/null +++ b/reference/FungibleMultiToken.scilla @@ -0,0 +1,195 @@ +scilla_version 0 + +(***************************************************) +(* Associated library *) +(***************************************************) +import IntUtils +library FungibleMultiToken + +let one_msg = + fun (msg : Message) => + let nil_msg = Nil {Message} in + Cons {Message} msg nil_msg + +let two_msgs = +fun (msg1 : Message) => +fun (msg2 : Message) => + let msgs_tmp = one_msg msg2 in + Cons {Message} msg1 msgs_tmp + +(* Error events *) +type Error = +| CodeIsSender +| CodeInsufficientFunds +| CodeInsufficientAllowance + +let make_error = + fun (result : Error) => + let result_code = + match result with + | CodeIsSender => Int32 -1 + | CodeInsufficientFunds => Int32 -2 + | CodeInsufficientAllowance => Int32 -3 + end + in + { _exception : "Error"; code : result_code } + +let zero = Uint128 0 + +(* Dummy user-defined ADT *) +type Unit = +| Unit + +let get_val = + fun (some_val: Option Uint128) => + match some_val with + | Some val => val + | None => zero + end + +(***************************************************) +(* The contract definition *) +(***************************************************) + +contract FungibleMultiToken +( + contract_owner: ByStr20, + name : String, + symbol: String, + decimals: Uint32, + init_supply : Uint128 +) + +(* Mutable fields *) + +field total_supply : Uint128 = init_supply + +field balances: Map ByStr20 Uint128 + = let emp_map = Emp ByStr20 Uint128 in + builtin put emp_map contract_owner init_supply + +field allowances: Map ByStr20 (Map ByStr20 Uint128) + = Emp ByStr20 (Map ByStr20 Uint128) + +(**************************************) +(* Procedures *) +(**************************************) + +procedure ThrowError(err : Error) + e = make_error err; + throw e +end + +procedure IsNotSender(address: ByStr20) + is_sender = builtin eq _sender address; + match is_sender with + | True => + err = CodeIsSender; + ThrowError err + | False => + end +end + +procedure AuthorizedMoveIfSufficientBalance(from: ByStr20, to: ByStr20, amount: Uint128) + o_from_bal <- balances[from]; + bal = get_val o_from_bal; + can_do = uint128_le amount bal; + match can_do with + | True => + (* Subtract amount from from and add it to to address *) + new_from_bal = builtin sub bal amount; + balances[from] := new_from_bal; + (* Adds amount to to address *) + get_to_bal <- balances[to]; + new_to_bal = match get_to_bal with + | Some bal => builtin add bal amount + | None => amount + end; + balances[to] := new_to_bal + | False => + (* Balance not sufficient *) + err = CodeInsufficientFunds; + ThrowError err + end +end + +(***************************************) +(* Transitions *) +(***************************************) + +(* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be increased as allowance for the approved_spender. *) +transition IncreaseAllowance(spender: ByStr20, amount: Uint128) + IsNotSender spender; + some_current_allowance <- allowances[_sender][spender]; + current_allowance = get_val some_current_allowance; + new_allowance = builtin add current_allowance amount; + allowances[_sender][spender] := new_allowance; + e = {_eventname : "IncreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + event e +end + +(* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) +transition DecreaseAllowance(spender: ByStr20, amount: Uint128) + IsNotSender spender; + some_current_allowance <- allowances[_sender][spender]; + current_allowance = get_val some_current_allowance; + new_allowance = + let amount_le_allowance = uint128_le amount current_allowance in + match amount_le_allowance with + | True => builtin sub current_allowance amount + | False => zero + end; + allowances[_sender][spender] := new_allowance; + e = {_eventname : "DecreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + event e +end + +(* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) +(* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be sent. *) +transition Transfer(to: ByStr20, amount: Uint128) + AuthorizedMoveIfSufficientBalance _sender to amount; + e = {_eventname : "TransferSuccess"; sender : _sender; recipient : to; amount : amount}; + event e; + (* Prevent sending to a contract address that does not support transfers of token *) + msg_to_recipient = {_tag : "RecipientAcceptTransfer"; _recipient : to; _amount : zero; + sender : _sender; recipient : to; amount : amount}; + msg_to_sender = {_tag : "TransferSuccessCallBack"; _recipient : _sender; _amount : zero; + sender : _sender; recipient : to; amount : amount}; + msgs = two_msgs msg_to_recipient msg_to_sender; + send msgs +end + +(* @dev: Move a given amount of tokens from one address to another using the allowance mechanism. The caller must be an approved_spender. *) +(* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param from: Address of the token_owner whose balance is decreased. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be transferred. *) +transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) + o_spender_allowed <- allowances[from][_sender]; + allowed = get_val o_spender_allowed; + can_do = uint128_le amount allowed; + match can_do with + | True => + AuthorizedMoveIfSufficientBalance from to amount; + e = {_eventname : "TransferFromSuccess"; initiator : _sender; sender : from; recipient : to; amount : amount}; + event e; + new_allowed = builtin sub allowed amount; + allowances[from][_sender] := new_allowed; + (* Prevent sending to a contract address that does not support transfers of token *) + msg_to_recipient = {_tag: "RecipientAcceptTransferFrom"; _recipient : to; _amount: zero; + initiator: _sender; sender : from; recipient: to; amount: amount}; + msg_to_sender = {_tag: "TransferFromSuccessCallBack"; _recipient: _sender; _amount: zero; + initiator: _sender; sender: from; recipient: to; amount: amount}; + msgs = two_msgs msg_to_recipient msg_to_sender; + send msgs + | False => + err = CodeInsufficientAllowance; + ThrowError err + end +end From 9cab80e4a7d2322ac06283758f3a2a7f20d94cbc Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 14:20:37 +0200 Subject: [PATCH 02/51] created initial (non-functional but compilable) ZRC5 contract --- example/zrc5/auth_operator.js | 51 -- example/zrc5/burn.js | 56 -- example/zrc5/decrease_allowance.js | 56 -- example/zrc5/deploy.js | 27 +- example/zrc5/increase_allowance.js | 56 -- example/zrc5/is_operator_for.js | 56 -- example/zrc5/mint.js | 56 -- example/zrc5/operator_send.js | 61 --- example/zrc5/revoke_operator.js | 51 -- example/zrc5/transfer.js | 56 -- example/zrc5/transfer_from.js | 61 --- example/zrc5/yarn.lock | 766 ++++++++++++++++++++++++++++ reference/FungibleMultiToken.scilla | 61 +-- 13 files changed, 795 insertions(+), 619 deletions(-) delete mode 100644 example/zrc5/auth_operator.js delete mode 100644 example/zrc5/burn.js delete mode 100644 example/zrc5/decrease_allowance.js delete mode 100644 example/zrc5/increase_allowance.js delete mode 100644 example/zrc5/is_operator_for.js delete mode 100644 example/zrc5/mint.js delete mode 100644 example/zrc5/operator_send.js delete mode 100644 example/zrc5/revoke_operator.js delete mode 100644 example/zrc5/transfer.js delete mode 100644 example/zrc5/transfer_from.js create mode 100644 example/zrc5/yarn.lock diff --git a/example/zrc5/auth_operator.js b/example/zrc5/auth_operator.js deleted file mode 100644 index 8f2e9698a..000000000 --- a/example/zrc5/auth_operator.js +++ /dev/null @@ -1,51 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'AuthorizeOperator', - [ - { - vname: 'operator', - type: 'ByStr20', - value: '0xF9814DFAF5b817b6Ccd2993d94348cC77b354575', - }, - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/burn.js b/example/zrc5/burn.js deleted file mode 100644 index db0975b2c..000000000 --- a/example/zrc5/burn.js +++ /dev/null @@ -1,56 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'Burn', - [ - { - vname: 'burn_account', - type: 'ByStr20', - value: `${address}`, - }, - { - vname: 'amount', - type: 'Uint128', - value: '10', - }, - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/decrease_allowance.js b/example/zrc5/decrease_allowance.js deleted file mode 100644 index 5a28498b9..000000000 --- a/example/zrc5/decrease_allowance.js +++ /dev/null @@ -1,56 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'DecreaseAllowance', - [ - { - vname: 'spender', - type: 'ByStr20', - value: "0xF9814DFAF5b817b6Ccd2993d94348cC77b354575", - }, - { - vname: 'amount', - type: 'Uint128', - value: "10", - } - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/deploy.js b/example/zrc5/deploy.js index 513172a78..b8eca608e 100644 --- a/example/zrc5/deploy.js +++ b/example/zrc5/deploy.js @@ -20,7 +20,7 @@ async function main() { const myGasPrice = units.toQa('2000', units.Units.Li); // Gas Price that will be used by all transactions console.log("start to deploy zrc2: "); - const code = fs.readFileSync("../../reference/FungibleToken-Operator.scilla").toString(); + const code = fs.readFileSync("../../reference/FungibleMultiToken.scilla").toString(); console.log("contract code is: "); console.log(code); const init = [ @@ -34,31 +34,6 @@ async function main() { vname: "contract_owner", type: "ByStr20", value: `${address}` - }, - { - vname: "name", - type: "String", - value: `USDT` - }, - { - vname: "symbol", - type: "String", - value: `USDT` - }, - { - vname: "decimals", - type: "Uint32", - value: `2` - }, - { - vname: "default_operators", - type: "List ByStr20", - value: ["0x501A70ffEAA3F31C1caccE3479e74713546BAA44", "0xBFe2445408C51CD8Ee6727541195b02c891109ee", "0x428A2aA43456FE7fd2De66E48C1fBf372eC10eAE"] - }, - { - vname: "init_supply", - type: "Uint128", - value: `100000000` } ]; console.log("init json is: "); diff --git a/example/zrc5/increase_allowance.js b/example/zrc5/increase_allowance.js deleted file mode 100644 index e15849e65..000000000 --- a/example/zrc5/increase_allowance.js +++ /dev/null @@ -1,56 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'IncreaseAllowance', - [ - { - vname: 'spender', - type: 'ByStr20', - value: "0xF9814DFAF5b817b6Ccd2993d94348cC77b354575", - }, - { - vname: 'amount', - type: 'Uint128', - value: "100", - } - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/is_operator_for.js b/example/zrc5/is_operator_for.js deleted file mode 100644 index c2ff465e5..000000000 --- a/example/zrc5/is_operator_for.js +++ /dev/null @@ -1,56 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'IsOperatorFor', - [ - { - vname: 'token_owner', - type: 'ByStr20', - value: `${address}`, - }, - { - vname: 'operator', - type: 'ByStr20', - value: '0x501A70ffEAA3F31C1caccE3479e74713546BAA44', - }, - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/mint.js b/example/zrc5/mint.js deleted file mode 100644 index 99cc0d17b..000000000 --- a/example/zrc5/mint.js +++ /dev/null @@ -1,56 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'Mint', - [ - { - vname: 'recipient', - type: 'ByStr20', - value: `${address}`, - }, - { - vname: 'amount', - type: 'Uint128', - value: '100000000', - }, - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/operator_send.js b/example/zrc5/operator_send.js deleted file mode 100644 index 247511c0c..000000000 --- a/example/zrc5/operator_send.js +++ /dev/null @@ -1,61 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '534b41b12c3c14e282279da256d85a9ce456e1d8cea4e2ef5c49c71e321b3eac'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'OperatorSend', - [ - { - vname: 'from', - type: 'ByStr20', - value: "0x501A70ffEAA3F31C1caccE3479e74713546BAA44", - }, - { - vname: 'to', - type: 'ByStr20', - value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", - }, - { - vname: 'amount', - type: 'Uint128', - value: '10', - }, - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/revoke_operator.js b/example/zrc5/revoke_operator.js deleted file mode 100644 index ac7942097..000000000 --- a/example/zrc5/revoke_operator.js +++ /dev/null @@ -1,51 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'RevokeOperator', - [ - { - vname: 'operator', - type: 'ByStr20', - value: '0xF9814DFAF5b817b6Ccd2993d94348cC77b354575', - }, - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/transfer.js b/example/zrc5/transfer.js deleted file mode 100644 index e882ee628..000000000 --- a/example/zrc5/transfer.js +++ /dev/null @@ -1,56 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'Transfer', - [ - { - vname: 'to', - type: 'ByStr20', - value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", - }, - { - vname: 'amount', - type: 'Uint128', - value: "100", - } - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/transfer_from.js b/example/zrc5/transfer_from.js deleted file mode 100644 index aa63c4640..000000000 --- a/example/zrc5/transfer_from.js +++ /dev/null @@ -1,61 +0,0 @@ -const {BN, Long, bytes, units} = require('@zilliqa-js/util'); -const {Zilliqa} = require('@zilliqa-js/zilliqa'); -const { - toBech32Address, - getAddressFromPrivateKey, -} = require('@zilliqa-js/crypto'); - - -async function main() { - const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); - const CHAIN_ID = 333; - const MSG_VERSION = 1; - const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); - privkey = '534b41b12c3c14e282279da256d85a9ce456e1d8cea4e2ef5c49c71e321b3eac'; - zilliqa.wallet.addByPrivateKey( - privkey - ); - const address = getAddressFromPrivateKey(privkey); - console.log("Your account address is:"); - console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - - - const ftAddr = toBech32Address("509ae6e5d91cee3c6571dcd04aa08288a29d563a"); - try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( - 'TransferFrom', - [ - { - vname: 'from', - type: 'ByStr20', - value: "0x501A70ffEAA3F31C1caccE3479e74713546BAA44", - }, - { - vname: 'to', - type: 'ByStr20', - value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", - }, - { - vname: 'amount', - type: 'Uint128', - value: "100", - } - ], - { - // amount, gasPrice and gasLimit must be explicitly provided - version: VERSION, - amount: new BN(0), - gasPrice: myGasPrice, - gasLimit: Long.fromNumber(10000), - } - ); - console.log(JSON.stringify(callTx.receipt, null, 4)); - - } catch (err) { - console.log(err); - } -} - -main(); diff --git a/example/zrc5/yarn.lock b/example/zrc5/yarn.lock new file mode 100644 index 000000000..372b94888 --- /dev/null +++ b/example/zrc5/yarn.lock @@ -0,0 +1,766 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + +"@types/bip39@^2.4.0": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@types/bip39/-/bip39-2.4.2.tgz#f5d6617212be496bb998d3969f657f77a10c5287" + integrity sha512-Vo9lqOIRq8uoIzEVrV87ZvcIM0PN9t0K3oYZ/CS61fIYKCBdOIM7mlWzXuRvSXrDtVa1uUO2w1cdfufxTC0bzg== + dependencies: + "@types/node" "*" + +"@types/bn.js@^4.11.3": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/hdkey@^0.7.0": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@types/hdkey/-/hdkey-0.7.1.tgz#9bc63ebbe96b107b277b65ea7a95442a677d0d61" + integrity sha512-4Kkr06hq+R8a9EzVNqXGOY2x1xA7dhY6qlp6OvaZ+IJy1BCca1Cv126RD9X7CMJoXoLo8WvAizy8gQHpqW6K0Q== + dependencies: + "@types/node" "*" + +"@types/long@^4.0.0", "@types/long@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + +"@types/node@*": + version "14.14.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.5.tgz#e92d3b8f76583efa26c1a63a21c9d3c1143daa29" + integrity sha512-H5Wn24s/ZOukBmDn03nnGTp18A60ny9AmCwnEcgJiTgSGsCO7k+NWP7zjCCbhlcnVCoI+co52dUAt9GMhOSULw== + +"@types/node@^13.7.0": + version "13.13.29" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.29.tgz#2d9362387bd125f02fb111e8fc81cca8e9aaa5b2" + integrity sha512-WPGpyEDx4/F4Rx1p1Zar8m+JsMxpSY/wNFPlyNXWV+UzJwkYt3LQg2be/qJgpsLdVJsfxTR5ipY6rv2579jStQ== + +"@zilliqa-js/account@0.8.9": + version "0.8.9" + resolved "https://registry.yarnpkg.com/@zilliqa-js/account/-/account-0.8.9.tgz#3a620c865727a0ae54b5d6ef1823ee0f26415cd3" + integrity sha512-bQ9sJKmszotzZ3Ha1qpzMam5VCyTa+AavtcItnl7vEVnKi9j3Iy2BmysKJhWKJF6fDeEQldJZh6egIpIanebTQ== + dependencies: + "@types/bip39" "^2.4.0" + "@types/hdkey" "^0.7.0" + "@zilliqa-js/core" "0.8.9" + "@zilliqa-js/crypto" "0.8.9" + "@zilliqa-js/proto" "0.8.3" + "@zilliqa-js/util" "0.8.8" + bip39 "^2.5.0" + hdkey "^1.1.0" + +"@zilliqa-js/blockchain@0.8.9": + version "0.8.9" + resolved "https://registry.yarnpkg.com/@zilliqa-js/blockchain/-/blockchain-0.8.9.tgz#98dcd8b3bfa76a12bd611eddbdc3de293784e384" + integrity sha512-T5exARCdTAQIU2/1lz4+t10Y0zcdl20Ul0QY2stot9XQkYocoFty8F8x4Hkc8ZY4OVOFbUg6+9PcBP8JBq9MAA== + dependencies: + "@zilliqa-js/account" "0.8.9" + "@zilliqa-js/contract" "0.8.9" + "@zilliqa-js/core" "0.8.9" + "@zilliqa-js/crypto" "0.8.9" + "@zilliqa-js/util" "0.8.8" + utility-types "^3.4.1" + +"@zilliqa-js/contract@0.8.9": + version "0.8.9" + resolved "https://registry.yarnpkg.com/@zilliqa-js/contract/-/contract-0.8.9.tgz#26f11c1fe3a816244fc17e3315dd995e01835d62" + integrity sha512-qDk3Anx/3brhpg7OgL4npEsBiYfiAfazbFKOOuByWkM4dyTI9sUYbx1rqUkq8QlhTW6tUJNoaTil/Qc2LqNgsQ== + dependencies: + "@zilliqa-js/account" "0.8.9" + "@zilliqa-js/blockchain" "0.8.9" + "@zilliqa-js/core" "0.8.9" + "@zilliqa-js/crypto" "0.8.9" + "@zilliqa-js/util" "0.8.8" + hash.js "^1.1.5" + utility-types "^2.1.0" + +"@zilliqa-js/core@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@zilliqa-js/core/-/core-0.8.3.tgz#9c9ff0d1b7ec60ec73011fe70d33c691afef5c28" + integrity sha512-3ZvAzLg5oPx18WSxyx6xDVSNp+2IYnhhxDe3in76aKpgurjAkdxWrhQRWpKNNrGtLNiQ2yn8vMDULxJCump3NQ== + dependencies: + "@zilliqa-js/crypto" "0.8.3" + "@zilliqa-js/util" "0.8.3" + cross-fetch "^2.2.2" + mitt "^1.1.3" + +"@zilliqa-js/core@0.8.9": + version "0.8.9" + resolved "https://registry.yarnpkg.com/@zilliqa-js/core/-/core-0.8.9.tgz#db5e0fa5c7b64a38da674d937525b7f26e44eab8" + integrity sha512-cH8XFzTL6kkjbDTG3zP8TrH0H5FEXRY/IfAW83Tf75qWa4y6X4IGvy4vZVCvzbkTlyuuFBCOmWA04YweaRfyKQ== + dependencies: + "@zilliqa-js/crypto" "0.8.9" + "@zilliqa-js/util" "0.8.8" + cross-fetch "^2.2.2" + mitt "^1.1.3" + +"@zilliqa-js/crypto@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@zilliqa-js/crypto/-/crypto-0.8.3.tgz#8e8550e5c3850ac4c9cafb09c927a883d563bf11" + integrity sha512-5O93xlmYr/UWtS1oA7d1mLWSY4oH7SThtGTi4G05r2pgT8Gy2/QYvff8Uhj/8TLi5/s5Qp3WmJeI+GF8rjq6og== + dependencies: + "@zilliqa-js/util" "0.8.3" + aes-js "^3.1.1" + bsert "^0.0.4" + elliptic "^6.5.0" + hash.js "^1.1.5" + hmac-drbg "^1.0.1" + pbkdf2 "^3.0.16" + randombytes "^2.0.6" + scryptsy "^2.1.0" + uuid "^3.3.2" + optionalDependencies: + scrypt.js "^0.3.0" + +"@zilliqa-js/crypto@0.8.9": + version "0.8.9" + resolved "https://registry.yarnpkg.com/@zilliqa-js/crypto/-/crypto-0.8.9.tgz#9dc346f4e3472903865db6f9913f2365bf402e07" + integrity sha512-0BSRbqVvIisFaJNKfa4J4X7yz1dD75Q+R2e71Q5CecVj0nlSDKkvXy+/ufbl/K+KrPWfK1DnNnZz4FSlNniJfw== + dependencies: + "@zilliqa-js/util" "0.8.8" + aes-js "^3.1.1" + bsert "^0.0.4" + elliptic "^6.5.0" + hash.js "^1.1.5" + hmac-drbg "^1.0.1" + pbkdf2 "^3.0.16" + randombytes "^2.0.6" + scryptsy "^2.1.0" + uuid "^3.3.2" + optionalDependencies: + scrypt.js "^0.3.0" + +"@zilliqa-js/proto@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@zilliqa-js/proto/-/proto-0.8.3.tgz#882cd22a06b57ab3a323974a5afc7061578ba805" + integrity sha512-VFFnDk+U2F7M1y0njy0LrIVrkSTFjSw0KoF+E6kPhp2Dz4xlLQ24lND6We4mJJDKLftKeLFJACDJBWl0CihVcA== + dependencies: + protobufjs "^6.8.8" + +"@zilliqa-js/subscriptions@0.8.6": + version "0.8.6" + resolved "https://registry.yarnpkg.com/@zilliqa-js/subscriptions/-/subscriptions-0.8.6.tgz#2da0ba157a8b2b9e5965954c7758b72bbfcfbc35" + integrity sha512-Jl60dz4xw82ahfUhHKZmgj4FXkEVpmC19tTb9Qs3JeJpf7pkvW4+D44wzDOwZLHULybMy6rY80VD4WhCa8qneg== + dependencies: + "@zilliqa-js/core" "0.8.3" + mock-socket "^9.0.2" + websocket "^1.0.28" + +"@zilliqa-js/util@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@zilliqa-js/util/-/util-0.8.3.tgz#8f191ef9fc74a9a5f7b7dc3046eb9b319b387a04" + integrity sha512-adcl6eVvsHQtYFLQYeozIIxDaY/y6y1MIIq4ShDKg/cFOJS1yLWLUA5jVHxEc+y9kRreXWrQdR2kAn1URhxdJA== + dependencies: + "@types/bn.js" "^4.11.3" + "@types/long" "^4.0.0" + bn.js "^4.11.8" + long "^4.0.0" + +"@zilliqa-js/util@0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@zilliqa-js/util/-/util-0.8.8.tgz#b66530caefa9664e3113fe81b42a5d40a3bb087d" + integrity sha512-VICSqItq2FJNqDXohThIhNOcWhsQWkNCGNaB8+2tml5yKTF8sJ3sALDqTIjt7q0AaoV0nTHndFg2q/9tJbManw== + dependencies: + "@types/bn.js" "^4.11.3" + "@types/long" "^4.0.0" + bn.js "^4.11.8" + long "^4.0.0" + +"@zilliqa-js/zilliqa@^0.8.9": + version "0.8.9" + resolved "https://registry.yarnpkg.com/@zilliqa-js/zilliqa/-/zilliqa-0.8.9.tgz#d341aa75a316f8ab5e4d793e9c663dc3078bfc48" + integrity sha512-42p903hdTX22qvIIzBtLxm5y1ZCmoCcwB3JAzQJP/s5y1o8QpWa1EyDx3VD1yg1chCYGmUWWysSjNRnF8V9jkw== + dependencies: + "@zilliqa-js/account" "0.8.9" + "@zilliqa-js/blockchain" "0.8.9" + "@zilliqa-js/contract" "0.8.9" + "@zilliqa-js/core" "0.8.9" + "@zilliqa-js/crypto" "0.8.9" + "@zilliqa-js/subscriptions" "0.8.6" + "@zilliqa-js/util" "0.8.8" + +aes-js@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== + +base-x@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" + integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== + dependencies: + safe-buffer "^5.0.1" + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bip39@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.6.0.tgz#9e3a720b42ec8b3fbe4038f1e445317b6a99321c" + integrity sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg== + dependencies: + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + unorm "^1.3.3" + +bip66@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= + dependencies: + safe-buffer "^5.0.1" + +bn.js@^4.11.8, bn.js@^4.4.0: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + dependencies: + base-x "^3.0.2" + +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +bsert@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/bsert/-/bsert-0.0.4.tgz#2b3c236357923f0625f948802a5f9b66c0383d0b" + integrity sha512-VReLe1aTaHRmf80YLOHUk8ONQ48SjseZP76GlNIDheD5REYByn/Mm9yrtI0/ZCaFrcfxzgpiw1/hMMCUOSMa3w== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +bufferutil@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.1.tgz#3a177e8e5819a1243fe16b63a199951a7ad8d4a7" + integrity sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA== + dependencies: + node-gyp-build "~3.7.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-fetch@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" + integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw== + dependencies: + node-fetch "2.1.2" + whatwg-fetch "2.0.4" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +drbg.js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs= + dependencies: + browserify-aes "^1.0.6" + create-hash "^1.1.2" + create-hmac "^1.1.4" + +elliptic@^6.5.0, elliptic@^6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.5: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hdkey@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.2.tgz#c60f9cf6f90fbf24a8a52ea06893f36a0108cd3e" + integrity sha512-PTQ4VKu0oRnCrYfLp04iQZ7T2Cxz0UsEXYauk2j8eh6PJXCpbXuCFhOmtIFtbET0i3PMWmHN9J11gU8LEgUljQ== + dependencies: + bs58check "^2.1.2" + safe-buffer "^5.1.1" + secp256k1 "^3.0.1" + +hmac-drbg@^1.0.0, hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +mitt@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d" + integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw== + +mock-socket@^9.0.2: + version "9.0.3" + resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.0.3.tgz#4bc6d2aea33191e4fed5ec71f039e2bbeb95e414" + integrity sha512-SxIiD2yE/By79p3cNAAXyLQWTvEFNEzcAO7PH+DzRqKSFaplAPFjiQLmw8ofmpCsZf+Rhfn2/xCJagpdGmYdTw== + dependencies: + url-parse "^1.4.4" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +nan@^2.0.8, nan@^2.14.0: + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-fetch@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + +node-gyp-build@~3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" + integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== + +pbkdf2@^3.0.16, pbkdf2@^3.0.3, pbkdf2@^3.0.9: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +protobufjs@^6.8.8: + version "6.10.1" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.1.tgz#e6a484dd8f04b29629e9053344e3970cccf13cd2" + integrity sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" "^13.7.0" + long "^4.0.0" + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +randombytes@^2.0.1, randombytes@^2.0.6: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +scrypt.js@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.3.0.tgz#6c62d61728ad533c8c376a2e5e3e86d41a95c4c0" + integrity sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A== + dependencies: + scryptsy "^1.2.1" + optionalDependencies: + scrypt "^6.0.2" + +scrypt@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" + integrity sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0= + dependencies: + nan "^2.0.8" + +scryptsy@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" + integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= + dependencies: + pbkdf2 "^3.0.3" + +scryptsy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" + integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== + +secp256k1@^3.0.1: + version "3.8.0" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d" + integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw== + dependencies: + bindings "^1.5.0" + bip66 "^1.1.5" + bn.js "^4.11.8" + create-hash "^1.2.0" + drbg.js "^1.0.1" + elliptic "^6.5.2" + nan "^2.14.0" + safe-buffer "^5.1.2" + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +tslib@^1.10.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" + integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +unorm@^1.3.3: + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== + +url-parse@^1.4.4: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +utf-8-validate@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.2.tgz#63cfbccd85dc1f2b66cf7a1d0eebc08ed056bfb3" + integrity sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw== + dependencies: + node-gyp-build "~3.7.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utility-types@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-2.1.0.tgz#0c78fc9f7eb424d14302222b4ddd13fdb17f44ab" + integrity sha512-/nP2gqavggo6l38rtQI/CdeV+2fmBGXVvHgj9kV2MAnms3TIi77Mz9BtapPFI0+GZQCqqom0vACQ+VlTTaCovw== + +utility-types@^3.4.1: + version "3.10.0" + resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" + integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +websocket@^1.0.28: + version "1.0.32" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" + integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla index dfb086b15..5ee5ce264 100644 --- a/reference/FungibleMultiToken.scilla +++ b/reference/FungibleMultiToken.scilla @@ -53,23 +53,18 @@ let get_val = contract FungibleMultiToken ( - contract_owner: ByStr20, - name : String, - symbol: String, - decimals: Uint32, - init_supply : Uint128 + contract_owner: ByStr20 ) (* Mutable fields *) -field total_supply : Uint128 = init_supply +field total_supply : Map Uint64 Uint128 = init_supply -field balances: Map ByStr20 Uint128 - = let emp_map = Emp ByStr20 Uint128 in - builtin put emp_map contract_owner init_supply +field balances: Map Uint64 (Map ByStr20 Uint128) + = let emp_map = Map Uint64 (Map ByStr20 Uint128) -field allowances: Map ByStr20 (Map ByStr20 Uint128) - = Emp ByStr20 (Map ByStr20 Uint128) +field allowances: Map Uint64 (Map ByStr20 (Map ByStr20 Uint128)) + = Emp Map Uint64 (ByStr20 (Map ByStr20 Uint128)) (**************************************) (* Procedures *) @@ -90,8 +85,8 @@ procedure IsNotSender(address: ByStr20) end end -procedure AuthorizedMoveIfSufficientBalance(from: ByStr20, to: ByStr20, amount: Uint128) - o_from_bal <- balances[from]; +procedure AuthorizedMoveIfSufficientBalance(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint128) + o_from_bal <- balances[token][from]; bal = get_val o_from_bal; can_do = uint128_le amount bal; match can_do with @@ -120,22 +115,22 @@ end (* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) (* param spender: Address of the designated approved_spender. *) (* param amount: Number of tokens to be increased as allowance for the approved_spender. *) -transition IncreaseAllowance(spender: ByStr20, amount: Uint128) +transition IncreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) IsNotSender spender; - some_current_allowance <- allowances[_sender][spender]; + some_current_allowance <- allowances[token][_sender][spender]; current_allowance = get_val some_current_allowance; new_allowance = builtin add current_allowance amount; - allowances[_sender][spender] := new_allowance; - e = {_eventname : "IncreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + allowances[token][_sender][spender] := new_allowance; + e = {_eventname : "IncreasedAllowance"; token_owner : _sender; token: token; spender: spender; new_allowance : new_allowance}; event e end (* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) (* param spender: Address of the designated approved_spender. *) (* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) -transition DecreaseAllowance(spender: ByStr20, amount: Uint128) +transition DecreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) IsNotSender spender; - some_current_allowance <- allowances[_sender][spender]; + some_current_allowance <- allowances[token][_sender][spender]; current_allowance = get_val some_current_allowance; new_allowance = let amount_le_allowance = uint128_le amount current_allowance in @@ -143,8 +138,8 @@ transition DecreaseAllowance(spender: ByStr20, amount: Uint128) | True => builtin sub current_allowance amount | False => zero end; - allowances[_sender][spender] := new_allowance; - e = {_eventname : "DecreasedAllowance"; token_owner : _sender; spender: spender; new_allowance : new_allowance}; + allowances[token][_sender][spender] := new_allowance; + e = {_eventname : "DecreasedAllowance"; token_owner : _sender; token: token; spender: spender; new_allowance : new_allowance}; event e end @@ -152,14 +147,14 @@ end (* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be sent. *) -transition Transfer(to: ByStr20, amount: Uint128) - AuthorizedMoveIfSufficientBalance _sender to amount; - e = {_eventname : "TransferSuccess"; sender : _sender; recipient : to; amount : amount}; +transition Transfer(token: Uint64; to: ByStr20, amount: Uint128) + AuthorizedMoveIfSufficientBalance token _sender to amount; + e = {_eventname : "TransferSuccess"; token : Uint64; sender : _sender; recipient : to; amount : amount}; event e; (* Prevent sending to a contract address that does not support transfers of token *) - msg_to_recipient = {_tag : "RecipientAcceptTransfer"; _recipient : to; _amount : zero; + msg_to_recipient = {_tag : "RecipientAcceptTransfer"; _token: token; _recipient : to; _amount : zero; sender : _sender; recipient : to; amount : amount}; - msg_to_sender = {_tag : "TransferSuccessCallBack"; _recipient : _sender; _amount : zero; + msg_to_sender = {_tag : "TransferSuccessCallBack"; _token: token; _recipient : _sender; _amount : zero; sender : _sender; recipient : to; amount : amount}; msgs = two_msgs msg_to_recipient msg_to_sender; send msgs @@ -170,21 +165,21 @@ end (* @param from: Address of the token_owner whose balance is decreased. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be transferred. *) -transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) - o_spender_allowed <- allowances[from][_sender]; +transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint128) + o_spender_allowed <- allowances[token][from][_sender]; allowed = get_val o_spender_allowed; can_do = uint128_le amount allowed; match can_do with | True => - AuthorizedMoveIfSufficientBalance from to amount; - e = {_eventname : "TransferFromSuccess"; initiator : _sender; sender : from; recipient : to; amount : amount}; + AuthorizedMoveIfSufficientBalance token from to amount; + e = {_eventname : "TransferFromSuccess"; token: Uin64; initiator : _sender; sender : from; recipient : to; amount : amount}; event e; new_allowed = builtin sub allowed amount; - allowances[from][_sender] := new_allowed; + allowances[token][from][_sender] := new_allowed; (* Prevent sending to a contract address that does not support transfers of token *) - msg_to_recipient = {_tag: "RecipientAcceptTransferFrom"; _recipient : to; _amount: zero; + msg_to_recipient = {_tag: "RecipientAcceptTransferFrom"; _token: token; _recipient : to; _amount: zero; initiator: _sender; sender : from; recipient: to; amount: amount}; - msg_to_sender = {_tag: "TransferFromSuccessCallBack"; _recipient: _sender; _amount: zero; + msg_to_sender = {_tag: "TransferFromSuccessCallBack"; _token: token; _recipient: _sender; _amount: zero; initiator: _sender; sender: from; recipient: to; amount: amount}; msgs = two_msgs msg_to_recipient msg_to_sender; send msgs From 3eafa8f5e1da452aefe256734ec5aa6f56fdd921 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 14:55:06 +0200 Subject: [PATCH 03/51] made compilable --- reference/FungibleMultiToken.scilla | 30 ++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla index 5ee5ce264..09397a6f4 100644 --- a/reference/FungibleMultiToken.scilla +++ b/reference/FungibleMultiToken.scilla @@ -58,13 +58,15 @@ contract FungibleMultiToken (* Mutable fields *) -field total_supply : Map Uint64 Uint128 = init_supply +field max_token: Uint64 = Uint64 0 + +field total_supply : Map Uint64 Uint128 = Emp Uint64 Uint128 field balances: Map Uint64 (Map ByStr20 Uint128) - = let emp_map = Map Uint64 (Map ByStr20 Uint128) + = Emp Uint64 (Map ByStr20 Uint128) field allowances: Map Uint64 (Map ByStr20 (Map ByStr20 Uint128)) - = Emp Map Uint64 (ByStr20 (Map ByStr20 Uint128)) + = Emp Uint64 (Map ByStr20 (Map ByStr20 Uint128)) (**************************************) (* Procedures *) @@ -93,14 +95,14 @@ procedure AuthorizedMoveIfSufficientBalance(token: Uint64, from: ByStr20, to: By | True => (* Subtract amount from from and add it to to address *) new_from_bal = builtin sub bal amount; - balances[from] := new_from_bal; + balances[token][from] := new_from_bal; (* Adds amount to to address *) - get_to_bal <- balances[to]; + get_to_bal <- balances[token][to]; new_to_bal = match get_to_bal with | Some bal => builtin add bal amount | None => amount end; - balances[to] := new_to_bal + balances[token][to] := new_to_bal | False => (* Balance not sufficient *) err = CodeInsufficientFunds; @@ -112,6 +114,16 @@ end (* Transitions *) (***************************************) +transition CreateToken() + id <- max_token; + id2 = let one = Uint64 1 in builtin add id one; + max_token := id2; + zero = Uint128 0; + total_supply[id2] := zero; + e = {_eventname : "CreatedToken"; token_owner : _sender; token: id2}; + event e +end + (* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) (* param spender: Address of the designated approved_spender. *) (* param amount: Number of tokens to be increased as allowance for the approved_spender. *) @@ -147,9 +159,9 @@ end (* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be sent. *) -transition Transfer(token: Uint64; to: ByStr20, amount: Uint128) +transition Transfer(token: Uint64, to: ByStr20, amount: Uint128) AuthorizedMoveIfSufficientBalance token _sender to amount; - e = {_eventname : "TransferSuccess"; token : Uint64; sender : _sender; recipient : to; amount : amount}; + e = {_eventname : "TransferSuccess"; token : token; sender : _sender; recipient : to; amount : amount}; event e; (* Prevent sending to a contract address that does not support transfers of token *) msg_to_recipient = {_tag : "RecipientAcceptTransfer"; _token: token; _recipient : to; _amount : zero; @@ -172,7 +184,7 @@ transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 match can_do with | True => AuthorizedMoveIfSufficientBalance token from to amount; - e = {_eventname : "TransferFromSuccess"; token: Uin64; initiator : _sender; sender : from; recipient : to; amount : amount}; + e = {_eventname : "TransferFromSuccess"; token: token; initiator : _sender; sender : from; recipient : to; amount : amount}; event e; new_allowed = builtin sub allowed amount; allowances[token][from][_sender] := new_allowed; From e2dfd67997ef7aa872ef91f9693426cc6b2640af Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 15:02:30 +0200 Subject: [PATCH 04/51] creating mirrored tokens --- reference/FungibleMultiToken.scilla | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla index 09397a6f4..d5ad00738 100644 --- a/reference/FungibleMultiToken.scilla +++ b/reference/FungibleMultiToken.scilla @@ -68,6 +68,8 @@ field balances: Map Uint64 (Map ByStr20 Uint128) field allowances: Map Uint64 (Map ByStr20 (Map ByStr20 Uint128)) = Emp Uint64 (Map ByStr20 (Map ByStr20 Uint128)) +field mirrored_zrc2: Map Uint64 ByStr20 = Emp Uint64 ByStr20 + (**************************************) (* Procedures *) (**************************************) @@ -114,16 +116,19 @@ end (* Transitions *) (***************************************) -transition CreateToken() +transition CreateZRC2BridgeToken(zrc2_contract: ByStr20) id <- max_token; - id2 = let one = Uint64 1 in builtin add id one; - max_token := id2; + token = let one = Uint64 1 in builtin add id one; + max_token := token; zero = Uint128 0; - total_supply[id2] := zero; - e = {_eventname : "CreatedToken"; token_owner : _sender; token: id2}; + total_supply[token] := zero; + mirrored_zrc2[token] := zrc2_contract; + e = {_eventname : "CreatedToken"; token_owner : _sender; token: token}; event e end +(* TODO: Be able to retrieve mirrored_zrc2 *) + (* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) (* param spender: Address of the designated approved_spender. *) (* param amount: Number of tokens to be increased as allowance for the approved_spender. *) From 594dfa849c33836f5b39005510e91a73a8a22671 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 15:50:36 +0200 Subject: [PATCH 05/51] made working contract --- reference/FungibleMultiToken.scilla | 54 ++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla index d5ad00738..d2291fe77 100644 --- a/reference/FungibleMultiToken.scilla +++ b/reference/FungibleMultiToken.scilla @@ -68,7 +68,8 @@ field balances: Map Uint64 (Map ByStr20 Uint128) field allowances: Map Uint64 (Map ByStr20 (Map ByStr20 Uint128)) = Emp Uint64 (Map ByStr20 (Map ByStr20 Uint128)) -field mirrored_zrc2: Map Uint64 ByStr20 = Emp Uint64 ByStr20 +field zrc2_to_token: Map ByStr20 Uint64 = Emp ByStr20 Uint64 +(*field token_to_zrc2: Map Uint64 ByStr20 = Emp Uint64 ByStr20*) (**************************************) (* Procedures *) @@ -120,14 +121,14 @@ transition CreateZRC2BridgeToken(zrc2_contract: ByStr20) id <- max_token; token = let one = Uint64 1 in builtin add id one; max_token := token; - zero = Uint128 0; total_supply[token] := zero; - mirrored_zrc2[token] := zrc2_contract; + zrc2_to_token[zrc2_contract] := token; + (*token_to_zrc2[token] := zrc2_contract;*) e = {_eventname : "CreatedToken"; token_owner : _sender; token: token}; event e end -(* TODO: Be able to retrieve mirrored_zrc2 *) +(* TODO: Be able to retrieve zrc2_to_token *) (* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) (* param spender: Address of the designated approved_spender. *) @@ -205,3 +206,48 @@ transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 ThrowError err end end + +(* ZRC2 bridge *) + +procedure DoAcceptTransfer(sender: ByStr20, recipient: ByStr20, amount: Uint128) + o_token <- zrc2_to_token[_sender]; + match o_token with + | Some token => + o_balance <- balances[token][sender]; + balance = get_val o_balance; + balance = builtin add balance amount; + balances[token][sender] := balance; + o_our_total_supply <- total_supply[token]; + our_total_supply = get_val o_our_total_supply; + our_total_supply = builtin add our_total_supply amount; + total_supply[token] := our_total_supply; + (* TODO: Should `minter` be `sender` or `_sender`? *) + e = {_eventname: "Minted"; minter: sender; recipient: recipient; amount: amount}; + event e + | None => + e = {_exception: "TokenDoesNotExist"; token: sender}; + throw e + end +end + +transition RecipientAcceptTransfer(sender: ByStr20, recipient: ByStr20, amount: Uint128) + DoAcceptTransfer sender recipient amount +end + +transition RecipientAcceptTransferFrom(initiator: ByStr20, sender : ByStr20, recipient: ByStr20, amount: Uint128) + DoAcceptTransfer sender recipient amount +end + +transition Withdraw(token: Uint64, amount: Uint128) + o_balance <- balances[token][_sender]; + balance = get_val o_balance; + balance = builtin sub balance amount; + balances[token][_sender] := balance; + o_our_total_supply <- total_supply[token]; + our_total_supply = get_val o_our_total_supply; + our_total_supply = builtin sub our_total_supply amount; + total_supply[token] := our_total_supply; + (* TODO: Should `minter` be `sender` or `_sender`? *) + e = {_eventname: "Burnt"; burner: _sender; burn_account: _sender; amount: amount}; + event e +end \ No newline at end of file From 5638932700568e658b7a6a819afa203950f58703 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 16:04:58 +0200 Subject: [PATCH 06/51] contract updated --- reference/FungibleMultiToken.scilla | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla index d2291fe77..2062a9761 100644 --- a/reference/FungibleMultiToken.scilla +++ b/reference/FungibleMultiToken.scilla @@ -22,6 +22,7 @@ type Error = | CodeIsSender | CodeInsufficientFunds | CodeInsufficientAllowance +| CodeTokenDoesNotExist let make_error = fun (result : Error) => @@ -30,6 +31,7 @@ let make_error = | CodeIsSender => Int32 -1 | CodeInsufficientFunds => Int32 -2 | CodeInsufficientAllowance => Int32 -3 + | CodeTokenDoesNotExist => Int32 -4 end in { _exception : "Error"; code : result_code } @@ -80,6 +82,17 @@ procedure ThrowError(err : Error) throw e end +procedure TokenDoesNotExist(token: Uint64) + m <- max_token; + e = builtin lt token m; + match e with + | True => + | False => + err = CodeTokenDoesNotExist; + ThrowError err + end +end + procedure IsNotSender(address: ByStr20) is_sender = builtin eq _sender address; match is_sender with @@ -118,9 +131,9 @@ end (***************************************) transition CreateZRC2BridgeToken(zrc2_contract: ByStr20) - id <- max_token; - token = let one = Uint64 1 in builtin add id one; - max_token := token; + token <- max_token; + new_max = let one = Uint64 1 in builtin add token one; + max_token := new_max; total_supply[token] := zero; zrc2_to_token[zrc2_contract] := token; (*token_to_zrc2[token] := zrc2_contract;*) @@ -135,6 +148,7 @@ end (* param amount: Number of tokens to be increased as allowance for the approved_spender. *) transition IncreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) IsNotSender spender; + TokenDoesNotExist token; some_current_allowance <- allowances[token][_sender][spender]; current_allowance = get_val some_current_allowance; new_allowance = builtin add current_allowance amount; @@ -148,6 +162,7 @@ end (* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) transition DecreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) IsNotSender spender; + TokenDoesNotExist token; some_current_allowance <- allowances[token][_sender][spender]; current_allowance = get_val some_current_allowance; new_allowance = @@ -166,6 +181,7 @@ end (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be sent. *) transition Transfer(token: Uint64, to: ByStr20, amount: Uint128) + TokenDoesNotExist token; AuthorizedMoveIfSufficientBalance token _sender to amount; e = {_eventname : "TransferSuccess"; token : token; sender : _sender; recipient : to; amount : amount}; event e; @@ -184,6 +200,7 @@ end (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be transferred. *) transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint128) + TokenDoesNotExist token; o_spender_allowed <- allowances[token][from][_sender]; allowed = get_val o_spender_allowed; can_do = uint128_le amount allowed; @@ -225,8 +242,8 @@ procedure DoAcceptTransfer(sender: ByStr20, recipient: ByStr20, amount: Uint128) e = {_eventname: "Minted"; minter: sender; recipient: recipient; amount: amount}; event e | None => - e = {_exception: "TokenDoesNotExist"; token: sender}; - throw e + err = CodeTokenDoesNotExist; + ThrowError err end end @@ -239,6 +256,7 @@ transition RecipientAcceptTransferFrom(initiator: ByStr20, sender : ByStr20, rec end transition Withdraw(token: Uint64, amount: Uint128) + TokenDoesNotExist token; o_balance <- balances[token][_sender]; balance = get_val o_balance; balance = builtin sub balance amount; From 9df31e348a5542147dc4d43a5eb4349374bcb799 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 16:22:44 +0200 Subject: [PATCH 07/51] created a test file (yet wrong) --- example/zrc5/store.js | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 example/zrc5/store.js diff --git a/example/zrc5/store.js b/example/zrc5/store.js new file mode 100644 index 000000000..7c723f311 --- /dev/null +++ b/example/zrc5/store.js @@ -0,0 +1,56 @@ +const {BN, Long, bytes, units} = require('@zilliqa-js/util'); +const {Zilliqa} = require('@zilliqa-js/zilliqa'); +const { + toBech32Address, + getAddressFromPrivateKey, +} = require('@zilliqa-js/crypto'); + + +async function main() { + const zilliqa = new Zilliqa('https://dev-api.zilliqa.com'); + const CHAIN_ID = 333; + const MSG_VERSION = 1; + const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION); + privkey = '07e0b1d1870a0ba1b60311323cb9c198d6f6193b2219381c189afab3f5ac41a9'; + zilliqa.wallet.addByPrivateKey( + privkey + ); + const address = getAddressFromPrivateKey(privkey); + console.log("Your account address is:"); + console.log(`${address}`); + const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + + + const ftAddr = toBech32Address("9b80a12a68989575b7fd4b82a6dabee468ab9d92"); + try { + const contract = zilliqa.contracts.at(ftAddr); + const callTx = await contract.call( + 'Transfer', + [ + { + vname: 'to', + type: 'ByStr20', + value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", + }, + { + vname: 'amount', + type: 'Uint128', + value: "100", + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(callTx.receipt, null, 4)); + + } catch (err) { + console.log(err); + } +} + +main(); From c06cc67e6803d675c9f895750048580122c2541d Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 18:04:53 +0200 Subject: [PATCH 08/51] contract bug fix --- reference/FungibleMultiToken.scilla | 39 ++++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla index 2062a9761..e2994d01b 100644 --- a/reference/FungibleMultiToken.scilla +++ b/reference/FungibleMultiToken.scilla @@ -71,7 +71,7 @@ field allowances: Map Uint64 (Map ByStr20 (Map ByStr20 Uint128)) = Emp Uint64 (Map ByStr20 (Map ByStr20 Uint128)) field zrc2_to_token: Map ByStr20 Uint64 = Emp ByStr20 Uint64 -(*field token_to_zrc2: Map Uint64 ByStr20 = Emp Uint64 ByStr20*) +field token_to_zrc2: Map Uint64 ByStr20 = Emp Uint64 ByStr20 (**************************************) (* Procedures *) @@ -136,7 +136,7 @@ transition CreateZRC2BridgeToken(zrc2_contract: ByStr20) max_token := new_max; total_supply[token] := zero; zrc2_to_token[zrc2_contract] := token; - (*token_to_zrc2[token] := zrc2_contract;*) + token_to_zrc2[token] := zrc2_contract; e = {_eventname : "CreatedToken"; token_owner : _sender; token: token}; event e end @@ -255,17 +255,26 @@ transition RecipientAcceptTransferFrom(initiator: ByStr20, sender : ByStr20, rec DoAcceptTransfer sender recipient amount end -transition Withdraw(token: Uint64, amount: Uint128) - TokenDoesNotExist token; - o_balance <- balances[token][_sender]; - balance = get_val o_balance; - balance = builtin sub balance amount; - balances[token][_sender] := balance; - o_our_total_supply <- total_supply[token]; - our_total_supply = get_val o_our_total_supply; - our_total_supply = builtin sub our_total_supply amount; - total_supply[token] := our_total_supply; - (* TODO: Should `minter` be `sender` or `_sender`? *) - e = {_eventname: "Burnt"; burner: _sender; burn_account: _sender; amount: amount}; - event e +transition Withdraw(token: Uint64, to: ByStr20, amount: Uint128) + o_zrc2 <- token_to_zrc2[token]; + match o_zrc2 with + | Some zrc2 => + o_balance <- balances[token][_sender]; + balance = get_val o_balance; + balance = builtin sub balance amount; + balances[token][_sender] := balance; + o_our_total_supply <- total_supply[token]; + our_total_supply = get_val o_our_total_supply; + our_total_supply = builtin sub our_total_supply amount; + total_supply[token] := our_total_supply; + msg = {_tag : "Transfer"; to : to; amount : amount; _amount : zero; _recipient : zrc2}; + msgs = one_msg msg; + send msgs; + (* TODO: Should `minter` be `sender` or `_sender`? *) + e = {_eventname: "Burnt"; burner: _sender; burn_account: _sender; amount: amount}; + event e + | None => + err = CodeTokenDoesNotExist; + ThrowError err + end end \ No newline at end of file From 978eedff015e8e1f64ab40453a04e9979dd38d00 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Tue, 27 Oct 2020 18:06:46 +0200 Subject: [PATCH 09/51] a test almost finished --- example/zrc5/store.js | 98 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 5 deletions(-) diff --git a/example/zrc5/store.js b/example/zrc5/store.js index 7c723f311..91e70d37a 100644 --- a/example/zrc5/store.js +++ b/example/zrc5/store.js @@ -21,16 +21,104 @@ async function main() { const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions - const ftAddr = toBech32Address("9b80a12a68989575b7fd4b82a6dabee468ab9d92"); + const ftAddrHuman = "509ae6e5d91cee3c6571dcd04aa08288a29d563a"; + const mtAddrHuman = "9b80a12a68989575b7fd4b82a6dabee468ab9d92"; + const ftAddr = toBech32Address('0x'+ftAddrHuman); + const mtAddr = toBech32Address('0x'+mtAddrHuman); + const receiptAddrHuman = "BFe2445408C51CD8Ee6727541195b02c891109ee"; + try { - const contract = zilliqa.contracts.at(ftAddr); - const callTx = await contract.call( + const ftContract = zilliqa.contracts.at(ftAddr); + const mtContract = zilliqa.contracts.at(mtAddr); + + const createTokenCallTx = await mtContract.call( + 'Transfer', + [ + { + vname: 'CreateZRC2BridgeToken', + type: 'ByStr20', + value: '0x'+ftAddrHuman, + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(createTokenCallTx/*.receipt*/, null, 4)); + return; + + const confirmedCreateTokenCallTx = await createTokenCallTx.confirm(createTokenCallTx.id); + console.log(JSON.stringify(confirmedCreateTokenCallTx.receipt, null, 4)); + + const depositCallTx = await ftContract.call( 'Transfer', [ { vname: 'to', type: 'ByStr20', - value: "0xBFe2445408C51CD8Ee6727541195b02c891109ee", + value: mtAddr, + }, + { + vname: 'amount', + type: 'Uint128', + value: "100", + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(depositCallTx.receipt, null, 4)); + + const transferCallTx = await mtContract.call( + 'Transfer', + [ + { + vname: 'token', + type: 'Uint64', + value: ??, + }, + { + vname: 'to', + type: 'ByStr20', + value: receiptAddrHuman, + }, + { + vname: 'amount', + type: 'Uint128', + value: "100", + } + ], + { + // amount, gasPrice and gasLimit must be explicitly provided + version: VERSION, + amount: new BN(0), + gasPrice: myGasPrice, + gasLimit: Long.fromNumber(10000), + } + ); + console.log(JSON.stringify(transferCallTx.receipt, null, 4)); + + const withdrawCallTx = await mtContract.call( + 'Withdraw', + [ + { + vname: 'token', + type: 'Uint64', + value: ??, + }, + { + vname: 'to', + type: 'ByStr20', + value: receiptAddrHuman, }, { vname: 'amount', @@ -46,7 +134,7 @@ async function main() { gasLimit: Long.fromNumber(10000), } ); - console.log(JSON.stringify(callTx.receipt, null, 4)); + console.log(JSON.stringify(transferCallTx.receipt, null, 4)); } catch (err) { console.log(err); From 6ef537af1f6428c7ea0cc2a698e3cbcafa44af2b Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Wed, 28 Oct 2020 16:23:01 +0200 Subject: [PATCH 10/51] bug fixes --- example/zrc5/store.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/example/zrc5/store.js b/example/zrc5/store.js index 91e70d37a..519263c30 100644 --- a/example/zrc5/store.js +++ b/example/zrc5/store.js @@ -18,13 +18,13 @@ async function main() { const address = getAddressFromPrivateKey(privkey); console.log("Your account address is:"); console.log(`${address}`); - const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions + const myGasPrice = units.toQa('2000', units.Units.Li); // Gas Price that will be used by all transactions const ftAddrHuman = "509ae6e5d91cee3c6571dcd04aa08288a29d563a"; const mtAddrHuman = "9b80a12a68989575b7fd4b82a6dabee468ab9d92"; - const ftAddr = toBech32Address('0x'+ftAddrHuman); - const mtAddr = toBech32Address('0x'+mtAddrHuman); + const ftAddr = toBech32Address(ftAddrHuman); + const mtAddr = toBech32Address(mtAddrHuman); const receiptAddrHuman = "BFe2445408C51CD8Ee6727541195b02c891109ee"; try { @@ -32,10 +32,10 @@ async function main() { const mtContract = zilliqa.contracts.at(mtAddr); const createTokenCallTx = await mtContract.call( - 'Transfer', + 'CreateZRC2BridgeToken', [ { - vname: 'CreateZRC2BridgeToken', + vname: 'zrc2_contract', type: 'ByStr20', value: '0x'+ftAddrHuman, } @@ -48,11 +48,10 @@ async function main() { gasLimit: Long.fromNumber(10000), } ); - console.log(JSON.stringify(createTokenCallTx/*.receipt*/, null, 4)); - return; - - const confirmedCreateTokenCallTx = await createTokenCallTx.confirm(createTokenCallTx.id); - console.log(JSON.stringify(confirmedCreateTokenCallTx.receipt, null, 4)); + console.log(JSON.stringify(createTokenCallTx.receipt, null, 4)); + const tokenId = createTokenCallTx.receipt.event_logs.filter(e => e._eventname === "CreatedToken")[0] + .params.filter(p => p.vname === "token")[0].value; + console.log(`Created token #${tokenId}.`); const depositCallTx = await ftContract.call( 'Transfer', @@ -84,12 +83,12 @@ async function main() { { vname: 'token', type: 'Uint64', - value: ??, + value: tokenId, }, { vname: 'to', type: 'ByStr20', - value: receiptAddrHuman, + value: "0x"+receiptAddrHuman, }, { vname: 'amount', @@ -113,7 +112,7 @@ async function main() { { vname: 'token', type: 'Uint64', - value: ??, + value: tokenId, }, { vname: 'to', From 2fb4643ff9599dacd8980a6ef8d0a2a0bf2fe01d Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Wed, 28 Oct 2020 16:39:08 +0200 Subject: [PATCH 11/51] it works --- example/zrc5/store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/zrc5/store.js b/example/zrc5/store.js index 519263c30..2c6d7b06a 100644 --- a/example/zrc5/store.js +++ b/example/zrc5/store.js @@ -59,7 +59,7 @@ async function main() { { vname: 'to', type: 'ByStr20', - value: mtAddr, + value: "0x"+mtAddrHuman, }, { vname: 'amount', From 9fee92e9abcbf9178fa871f1eeef7cfdcfb5854e Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Wed, 28 Oct 2020 16:43:51 +0200 Subject: [PATCH 12/51] renamed wrongly named folder --- example/{zrc5 => zrc6}/deploy.js | 0 example/{zrc5 => zrc6}/package-lock.json | 0 example/{zrc5 => zrc6}/package.json | 0 example/{zrc5 => zrc6}/store.js | 0 example/{zrc5 => zrc6}/yarn.lock | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename example/{zrc5 => zrc6}/deploy.js (100%) rename example/{zrc5 => zrc6}/package-lock.json (100%) rename example/{zrc5 => zrc6}/package.json (100%) rename example/{zrc5 => zrc6}/store.js (100%) rename example/{zrc5 => zrc6}/yarn.lock (100%) diff --git a/example/zrc5/deploy.js b/example/zrc6/deploy.js similarity index 100% rename from example/zrc5/deploy.js rename to example/zrc6/deploy.js diff --git a/example/zrc5/package-lock.json b/example/zrc6/package-lock.json similarity index 100% rename from example/zrc5/package-lock.json rename to example/zrc6/package-lock.json diff --git a/example/zrc5/package.json b/example/zrc6/package.json similarity index 100% rename from example/zrc5/package.json rename to example/zrc6/package.json diff --git a/example/zrc5/store.js b/example/zrc6/store.js similarity index 100% rename from example/zrc5/store.js rename to example/zrc6/store.js diff --git a/example/zrc5/yarn.lock b/example/zrc6/yarn.lock similarity index 100% rename from example/zrc5/yarn.lock rename to example/zrc6/yarn.lock From bab593076fdc440d9c2a69ed1ca3b8b15d2a0ddf Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Wed, 28 Oct 2020 16:50:48 +0200 Subject: [PATCH 13/51] example/zrc6/ZRC-6.md --- example/zrc6/ZRC-6.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 example/zrc6/ZRC-6.md diff --git a/example/zrc6/ZRC-6.md b/example/zrc6/ZRC-6.md new file mode 100644 index 000000000..bd8fe8847 --- /dev/null +++ b/example/zrc6/ZRC-6.md @@ -0,0 +1,19 @@ +# ZRC-6 token example + +WARNING: The ZRC-6 standard is not yet finalished and even not yet +published. + +The example ZRC-6 token `FungibleMultiToken` accepts deposits of any +(registered with `CreateZRC2BridgeToken` transition) ZRC-2 token and +converts it 1-1 to a ZRC-6 token. The ZRC-6 tokens are held by +`FungibleMultiToken` contract and can be withdrawn back. + +This is useful for future applications when ZRC-2 will probably become +a so much outdated legacy that there will be no support for it, but we +would use ZRC-6 instead. + +For example, it allows to make a new version of $XSGD that will be ZRC-6 +based and easy convertible 1-1 forth and back from old ZRC-2 $XSGD. + +I will probably keep working on my ZRC-6 as a response to +https://gitcoin.co/issue/Zilliqa/zilliqa-bounties/1/100023732 \ No newline at end of file From 2b0d230c78bc9b3edf0757cd672f7407ba8ebd64 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 12:06:28 +0200 Subject: [PATCH 14/51] zrc-6.md created --- zrcs/zrc-6.md | 356 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 zrcs/zrc-6.md diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md new file mode 100644 index 000000000..9bb786e59 --- /dev/null +++ b/zrcs/zrc-6.md @@ -0,0 +1,356 @@ +| ZRC | Title | Status | Type | Author | Created (yyyy-mm-dd) | Updated (yyyy-mm-dd) | +| --- | ---------------------------- | -------- | -------- | ------------------------------------------------------------------------------------ | -------------------- | -------------------- | +| 2 | Standard for Fungible Tokens | Approved | Standard | Vaivaswatha Nagaraj
Chua Han Wen | 2019-11-18 | 2020-04-25 | + +## I. What are Fungible Tokens? + +The Fungible Token is an open standard for creating currencies. Fungibility is the property of goods or commodities whose individual units are essentially interchangeable, and each of its parts is indistinguishable from another part. + +## II. Abstract + +ZRC-2 defines a minimum interface that a smart contract must implement to allow fungible tokens to be managed, tracked, owned, and traded peer-to-peer via wallets or exchanges. + +## III. Motivation + +A standard for fungible tokens can serve as an interface for developers to create currencies, utility tokens or stable coins. Generally, fungible tokens can be used to represent interchangeable, identical and divisible assets as tokens. + +## IV. Specification + +The fungible token contract specification describes: + +1. the global error codes to be declared in the library part of the contract; +2. the names and types of the immutable and mutable variables (aka `fields`); +3. the transitions that will allow the changing of values of the mutable variables; +4. the events to be emitted by them. + +### A. Roles + +| Name | Description | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `contract_owner` | The owner of the contract initialized by the creator of the contract. | +| `token_owner` | A user (identified by an address) that owns tokens. | +| `approved_spender` | A user (identified by an address) that can transfer tokens on behalf of the token_owner. | +| `operator` | A user (identified by an address) that is approved to operate all tokens owned by another user (identified by another address). This role is optional. | +| `default_operator` | A special user (identified by an address) that is approved to operate all tokens owned by all users (identified by addresses). This role is optional. | + +### B. Error Codes + +The fungible token contract must define the following constants for use as error codes for the `Error` exception. + +| Name | Type | Code | Description | +| --------------------------- | ------- | ---- | ---------------------------------------------------------------------------------------------- | +| `CodeIsSender` | `Int32` | `-1` | Emit when an address is same as is the sender. | +| `CodeInsufficientFunds` | `Int32` | `-2` | Emit when there is insufficient balance to authorise transaction. | +| `CodeInsufficientAllowance` | `Int32` | `-3` | Emit when there is insufficient allowance to authorise transaction. | +| `CodeNotOwner` | `Int32` | `-4` | Emit when the sender is not contract_owner. This error code is optional. | +| `CodeNotApprovedOperator` | `Int32` | `-5` | Emit when caller is not an approved operator or default_operator. This error code is optional. | + +### C. Immutable Variables + +| Name | Type | Description | +| ------------------- | -------------- | -------------------------------------------------------------------------------------------------------------- | +| `contract_owner` | `ByStr20` | The owner of the contract initialized by the creator of the contract. | +| `name` | `String` | The name of the fungible token. | +| `symbol` | `String` | The symbol of the fungible token. | +| `decimals` | `Uint32` | The number of decimal places a token can be divided by. | +| `init_supply` | `Uint128` | The initial supply of fungible tokens when contract is created. | +| `default_operators` | `List ByStr20` | The list of default operators initialized by the creator of the contract. This immutable variable is optional. | + +### D. Mutable Fields + +| Name | Type | Description | +| --------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `total_supply` | `Uint128` | Total amount of tokens available. | +| `balances` | `Map ByStr20 Uint128` | Mapping between token owner to number of owned tokens. | +| `allowances` | `Map ByStr20 (Map ByStr20 Uint128)` | Mapping from token owner to approved spender address. Token owner can give an address an allowance of tokens to transfer tokens to other addresses. | +| `operators` | `Map ByStr20 (Map ByStr20 Unit)` | Mapping from token owner to designated operators. A token owner can approve an address as an operator (as per the definition of operator given above). This mapping is optional. | +| `revoked_default_operators` | `Map ByStr20 (Map ByStr20 Unit)` | Mapping from token owner to revoked default operators. Default operators are intialised by the contract owner. A token owner can revoked a default operator (as per the definition of default operator given above) at will. This mapping is optional. | + +### E. Getter Transitions + +#### 1. IsOperatorFor() (Optional) + +```ocaml +(* @dev: Check if an address is an operator or default operator of a token_owner. Throw if not. *) +(* @param operator: Address of a potential operator. *) +(* @param token_owner: Address of a token_owner. *) +transition IsOperatorFor(token_owner: ByStr20, operator: ByStr20) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ------------- | --------- | ----------------------------------------------------- | +| @param | `token_owner` | `ByStr20` | An address of a particular token_owner. | +| @param | `operator` | `ByStr20` | An address of a particular operator of a token_owner. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ----------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_tag` | `IsOperatorForCallBack` | Provide the sender a callback if specified address is indeed an approved operator of specified token_owner. | `token_owner` : `ByStr20`, `operator`: `ByStr20`, where `token_owner` is the address of the token_owner, `operator` is the address of the approved operator. | + +### F. Interface Transitions + +#### 1. Mint() (Optional) + +```ocaml +(* @dev: Mint new tokens. Only contract_owner can mint. *) +(* @param recipient: Address of the recipient whose balance is to increase. *) +(* @param amount: Number of tokens to be minted. *) +transition Mint(recipient: ByStr20, amount: Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ----------- | --------- | ------------------------------------------------------ | +| @param | `recipient` | `ByStr20` | Address of the recipient whose balance is to increase. | +| @param | `amount` | `Uint128` | Number of tokens to be minted. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | --------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_tag` | `RecipientAcceptMint` | Dummy callback to prevent invalid recipient contract. | `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `minter` is the address of the minter, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens minted. | +| `_tag` | `MintSuccessCallBack` | Provide the sender the status of the mint. | `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `minter` is the address of the minter, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens minted. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `Minted` | Minting is successful. | `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `minter` is the address of the minter, `recipient` is the address whose balance will be increased, and `amount` is the amount of fungible tokens minted. | +| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner. | + +#### 2. Burn() (Optional) + +```ocaml +(* @dev: Burn existing tokens. Only contract_owner can burn. *) +(* @param burn_account: Address of the token_owner whose balance is to decrease. *) +(* @param amount: Number of tokens to be burned. *) +transition Burn(burn_account: ByStr20, amount: Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | -------------- | --------- | -------------------------------------------------------- | +| @param | `burn_account` | `ByStr20` | Address of the token_owner whose balance is to decrease. | +| @param | `amount` | `Uint128` | Number of tokens to be burned. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | --------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_tag` | `BurnSuccessCallBack` | Provide the sender the status of the burn. | `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | ------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `Burnt` | Burning is successful. | `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | +| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of token_owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the token_owner. | + +#### 3. AuthorizeOperator() (Optional) + +```ocaml +(* @dev: Make an address an operator of the caller. *) +(* @param operator: Address to be authorize as operator or *) +(* Re-authorize as default_operator. Cannot be calling address. *) +transition AuthorizeOperator(operator: ByStr20) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ---------- | --------- | --------------------------------------------------------------------------------------------------- | +| @param | `operator` | `ByStr20` | Address to be authorize as operator or re-authorize as default_operator. Cannot be calling address. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `AuthorizeOperatorSuccess` | Authorizing is successful. | `authorizer`: `ByStr20` which is the caller's address, and `authorized_operator`: `ByStr20` which is the address to be authorized as an operator of the token_owner. | +| `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator. | + +#### 4. RevokeOperator() (Optional) + +```ocaml +(* @dev: Revoke an address from being an operator or default_operator of the caller. *) +(* @param operator: Address to be removed as operator or default_operator. *) +transition RevokeOperator(operator: ByStr20) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ---------- | --------- | -------------------------------- | +| @param | `operator` | `ByStr20` | Address to be unset as operator. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | ----------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `RevokeOperatorSuccess` | Revoking is successful. | `revoker`: `ByStr20` which is the caller's address, and `revoked_operator`: `ByStr20` which is the address to be removed as an operator of the token_owner. | +| `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner. | + +#### 5. IncreaseAllowance() + +```ocaml +(* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be increased as allowance for the approved_spender. *) +transition IncreaseAllowance(spender: ByStr20, amount: Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | --------- | --------- | ------------------------------------------------------------------------------- | +| @param | `spender` | `ByStr20` | Address of an approved_spender. | +| @param | `amount` | `Uint128` | Number of tokens to be increased as spending allowance of the approved_spender. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `IncreasedAllowance` | Increasing of allowance of an approved_spender is successful. | `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | +| `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | + +#### 6. DecreaseAllowance() + +```ocaml +(* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) +transition DecreaseAllowance(spender: ByStr20, amount: Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | --------- | --------- | ------------------------------------------------------------------------------- | +| @param | `spender` | `ByStr20` | Address of an approved_spender. | +| @param | `amount` | `Uint128` | Number of tokens to be decreased as spending allowance of the approved_spender. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `DecreasedAllowance` | Decreasing of allowance of an approved_spender is successful. | `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | +| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | + +#### 7. Transfer() + +```ocaml +(* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) +(* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be sent. *) +transition Transfer(to: ByStr20, amount: Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | -------- | --------- | ------------------------------------------------------ | +| @param | `to` | `ByStr20` | Address of the recipient whose balance is to increase. | +| @param | `amount` | `Uint128` | Amount of tokens to be sent. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_tag` | `RecipientAcceptTransfer` | Dummy callback to prevent invalid recipient contract. | `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `sender` is the address of the sender, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `TransferSuccessCallBack` | Provide the sender the status of the transfer. | `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `sender` is the address of the sender, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | ----------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `TransferSuccess` | Sending is successful. | `sender`: `ByStr20` which is the sender's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | + +#### 8. TransferFrom() + +```ocaml +(* @dev: Move a given amount of tokens from one address to another using the allowance mechanism. The caller must be an approved_spender. *) +(* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param from: Address of the token_owner whose balance is decreased. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be transferred. *) +transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | -------- | --------- | -------------------------------------------------------- | +| @param | `from` | `ByStr20` | Address of the token_owner whose balance is to decrease. | +| @param | `to` | `ByStr20` | Address of the recipient whose balance is to increase. | +| @param | `amount` | `Uint128` | Number of tokens to be transferred. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ----------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_tag` | `RecipientAcceptTransferFrom` | Dummy callback to prevent invalid recipient contract. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `TransferFromSuccessCallBack` | Provide the initiator the status of the transfer. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | + +**Events:** + +| | Name | Description | Event Parameters | +| ------------ | --------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_eventname` | `TransferFromSuccess` | Sending is successful. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | + +#### 9. OperatorSend() (Optional) + +```ocaml +(* @dev: Moves amount tokens from token_owner to recipient. _sender must be an operator of token_owner. *) +(* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param from: Address of the token_owner whose balance is decreased. *) +(* @param to: Address of the recipient whose balance is increased. *) +(* @param amount: Amount of tokens to be sent. *) +transition OperatorSend(from: ByStr20, to: ByStr20, amount: Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | -------- | --------- | -------------------------------------------------------- | +| @param | `from` | `ByStr20` | Address of the token_owner whose balance is to decrease. | +| @param | `to` | `ByStr20` | Address of the recipient whose balance is to increase. | +| @param | `amount` | `Uint128` | Amount of tokens to be sent. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ----------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_tag` | `RecipientAcceptOperatorSend` | Dummy callback to prevent invalid recipient contract. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an operator,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `OperatorSendSuccessCallBack` | Provide the operator the status of the transfer. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an operator,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | --------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `OperatorSendSuccess` | Sending is successful. | `initiator`: `ByStr20` which is the operator's address, `sender`: `ByStr20` which is the token_owner's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens to be transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred. | + +## V. Existing Implementation(s) + +- [ZRC2 Reference contract](../reference/FungibleToken.scilla) +- [ZRC2-Mintable Reference contract](../reference/FungibleToken-Mintable.scilla) +- [ZRC2-Operator Reference contract](../reference/FungibleToken-Operator.scilla) + +To test the reference contract, simply go to the [`example`](../example) folder and run one of the JS scripts. For example, to deploy the contract, run: + +```shell +yarn deploy.js +``` + +> **NOTE:** Please change the `privkey` in the script to your own private key. You can generate a testnet wallet and request for testnet \$ZIL at the [Nucleus Faucet](https://dev-wallet.zilliqa.com/home). + +## VI. Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 3546d1cb8c38d31e2fcefc79088ca1c9f0db8c64 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 13:10:06 +0200 Subject: [PATCH 15/51] added name, symbol, decimals, init_supply --- example/zrc6/deploy.js | 15 +++++++++++++++ reference/FungibleMultiToken.scilla | 15 ++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/example/zrc6/deploy.js b/example/zrc6/deploy.js index b8eca608e..2b849559e 100644 --- a/example/zrc6/deploy.js +++ b/example/zrc6/deploy.js @@ -34,6 +34,21 @@ async function main() { vname: "contract_owner", type: "ByStr20", value: `${address}` + }, + { + vname: "newName", + type: "String", + value: `A token` + }, + { + vname: "newSymbol", + type: "String", + value: `SYM` + }, + { + vname: "newDecimals", + type: "Uint32", + value: `18` } ]; console.log("init json is: "); diff --git a/reference/FungibleMultiToken.scilla b/reference/FungibleMultiToken.scilla index e2994d01b..a17f8b027 100644 --- a/reference/FungibleMultiToken.scilla +++ b/reference/FungibleMultiToken.scilla @@ -31,7 +31,7 @@ let make_error = | CodeIsSender => Int32 -1 | CodeInsufficientFunds => Int32 -2 | CodeInsufficientAllowance => Int32 -3 - | CodeTokenDoesNotExist => Int32 -4 + | CodeTokenDoesNotExist => Int32 -6 end in { _exception : "Error"; code : result_code } @@ -73,6 +73,11 @@ field allowances: Map Uint64 (Map ByStr20 (Map ByStr20 Uint128)) field zrc2_to_token: Map ByStr20 Uint64 = Emp ByStr20 Uint64 field token_to_zrc2: Map Uint64 ByStr20 = Emp Uint64 ByStr20 +field name : Map Uint64 String = Emp Uint64 String +field symbol : Map Uint64 String = Emp Uint64 String +field decimals : Map Uint64 Uint32 = Emp Uint64 Uint32 +field init_supply : Map Uint64 Uint128 = Emp Uint64 Uint128 + (**************************************) (* Procedures *) (**************************************) @@ -130,11 +135,15 @@ end (* Transitions *) (***************************************) -transition CreateZRC2BridgeToken(zrc2_contract: ByStr20) +transition CreateZRC2BridgeToken(zrc2_contract: ByStr20, newName : String, newSymbol : String, newDecimals : Uint32) token <- max_token; new_max = let one = Uint64 1 in builtin add token one; max_token := new_max; - total_supply[token] := zero; + name[token] := newName; + symbol[token] := newSymbol; + decimals[token] := newDecimals; + total_supply[token] := zero; (* FIXME: https://github.com/Zilliqa/scilla/issues/901 *) + init_supply[token] := zero; (* FIXME: ditto *) zrc2_to_token[zrc2_contract] := token; token_to_zrc2[token] := zrc2_contract; e = {_eventname : "CreatedToken"; token_owner : _sender; token: token}; From 6581e9db129049d2a3c6eeb1567c2751876813f1 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 13:39:13 +0200 Subject: [PATCH 16/51] preliminary version of ZRC-6 --- zrcs/zrc-6.md | 130 ++++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 56 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 9bb786e59..0c2060997 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -1,22 +1,22 @@ -| ZRC | Title | Status | Type | Author | Created (yyyy-mm-dd) | Updated (yyyy-mm-dd) | -| --- | ---------------------------- | -------- | -------- | ------------------------------------------------------------------------------------ | -------------------- | -------------------- | -| 2 | Standard for Fungible Tokens | Approved | Standard | Vaivaswatha Nagaraj
Chua Han Wen | 2019-11-18 | 2020-04-25 | +| ZRC | Title | Status | Type | Author | Created (yyyy-mm-dd) | Updated (yyyy-mm-dd) | +| --- | ---------------------------- | ------ | -------- | ------------------------------- | -------------------- | +| 2 | Standard for Multiple Tokens | Draft | Standard | Victor Porton | 2020-10-30 | ## I. What are Fungible Tokens? -The Fungible Token is an open standard for creating currencies. Fungibility is the property of goods or commodities whose individual units are essentially interchangeable, and each of its parts is indistinguishable from another part. +This standard allows a contract to "contain" both fungible (like ZRC-2) and non-fungible (like ZRC-1) tokens. Up to 2**64 tokens per single contract are supported. ## II. Abstract -ZRC-2 defines a minimum interface that a smart contract must implement to allow fungible tokens to be managed, tracked, owned, and traded peer-to-peer via wallets or exchanges. +ZRC-6 defines a minimum interface that a smart contract must implement to allow (multiple) tokens to be managed, tracked, owned, and traded peer-to-peer via wallets or exchanges. ## III. Motivation -A standard for fungible tokens can serve as an interface for developers to create currencies, utility tokens or stable coins. Generally, fungible tokens can be used to represent interchangeable, identical and divisible assets as tokens. +This standard serves as an interface for developers to create non-fungible tokens, currencies, utility tokens or stable coins. Allowing a single contract to create multiple tokens may sometimes much reduce gas usage when creating and/or interoperating multiple tokens. ## IV. Specification -The fungible token contract specification describes: +The multiple token contract specification describes: 1. the global error codes to be declared in the library part of the contract; 2. the names and types of the immutable and mutable variables (aka `fields`); @@ -42,25 +42,26 @@ The fungible token contract must define the following constants for use as error | `CodeIsSender` | `Int32` | `-1` | Emit when an address is same as is the sender. | | `CodeInsufficientFunds` | `Int32` | `-2` | Emit when there is insufficient balance to authorise transaction. | | `CodeInsufficientAllowance` | `Int32` | `-3` | Emit when there is insufficient allowance to authorise transaction. | -| `CodeNotOwner` | `Int32` | `-4` | Emit when the sender is not contract_owner. This error code is optional. | +| `CodeNotOwner` | `Int32` | `-4` | Emit when the sender is not a relevant owner. This error code is optional. | | `CodeNotApprovedOperator` | `Int32` | `-5` | Emit when caller is not an approved operator or default_operator. This error code is optional. | +| `CodeTokenDoesNotExist` | `Int32` | `-6` | Emit when trying to use a non-existing token. | ### C. Immutable Variables | Name | Type | Description | | ------------------- | -------------- | -------------------------------------------------------------------------------------------------------------- | | `contract_owner` | `ByStr20` | The owner of the contract initialized by the creator of the contract. | -| `name` | `String` | The name of the fungible token. | -| `symbol` | `String` | The symbol of the fungible token. | -| `decimals` | `Uint32` | The number of decimal places a token can be divided by. | -| `init_supply` | `Uint128` | The initial supply of fungible tokens when contract is created. | | `default_operators` | `List ByStr20` | The list of default operators initialized by the creator of the contract. This immutable variable is optional. | ### D. Mutable Fields | Name | Type | Description | | --------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `total_supply` | `Uint128` | Total amount of tokens available. | +| `name` | `Map ByStr20 String` | The name of the tokens. | +| `symbol` | `Map ByStr20 String` | The symbol of the tokens. | +| `decimals` | `Map ByStr20 Uint32` | The number of decimal places a token can be divided by. | +| `init_supply` | `Map ByStr20 Uint128` | The initial supply of tokens when a token is created. | +| `total_supply` | `Map ByStr20 Uint128` | Total amount of tokens available. | | `balances` | `Map ByStr20 Uint128` | Mapping between token owner to number of owned tokens. | | `allowances` | `Map ByStr20 (Map ByStr20 Uint128)` | Mapping from token owner to approved spender address. Token owner can give an address an allowance of tokens to transfer tokens to other addresses. | | `operators` | `Map ByStr20 (Map ByStr20 Unit)` | Mapping from token owner to designated operators. A token owner can approve an address as an operator (as per the definition of operator given above). This mapping is optional. | @@ -72,15 +73,17 @@ The fungible token contract must define the following constants for use as error ```ocaml (* @dev: Check if an address is an operator or default operator of a token_owner. Throw if not. *) +(* @param token: Token ID. *) (* @param operator: Address of a potential operator. *) (* @param token_owner: Address of a token_owner. *) -transition IsOperatorFor(token_owner: ByStr20, operator: ByStr20) +transition IsOperatorFor(token: Uint64, token_owner: ByStr20, operator: ByStr20) ``` **Arguments:** | | Name | Type | Description | | ------ | ------------- | --------- | ----------------------------------------------------- | +| @param | `token` | `ByStr20` | A token ID. | | @param | `token_owner` | `ByStr20` | An address of a particular token_owner. | | @param | `operator` | `ByStr20` | An address of a particular operator of a token_owner. | @@ -88,7 +91,7 @@ transition IsOperatorFor(token_owner: ByStr20, operator: ByStr20) | | Name | Description | Callback Parameters | | ------ | ----------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `_tag` | `IsOperatorForCallBack` | Provide the sender a callback if specified address is indeed an approved operator of specified token_owner. | `token_owner` : `ByStr20`, `operator`: `ByStr20`, where `token_owner` is the address of the token_owner, `operator` is the address of the approved operator. | +| `_tag` | `IsOperatorForCallBack` | Provide the sender a callback if specified address is indeed an approved operator of specified token_owner. | `token` : `Uint64`, `token_owner` : `ByStr20`, `operator`: `ByStr20`, where `token_owner` is the address of the token_owner, `operator` is the address of the approved operator. | ### F. Interface Transitions @@ -96,15 +99,17 @@ transition IsOperatorFor(token_owner: ByStr20, operator: ByStr20) ```ocaml (* @dev: Mint new tokens. Only contract_owner can mint. *) +(* @param token: Token ID. *) (* @param recipient: Address of the recipient whose balance is to increase. *) (* @param amount: Number of tokens to be minted. *) -transition Mint(recipient: ByStr20, amount: Uint128) +transition Mint(token: ByStr20, recipient: ByStr20, amount: Uint128) ``` **Arguments:** | | Name | Type | Description | | ------ | ----------- | --------- | ------------------------------------------------------ | +| @param | `token` | `ByStr20` | A token ID. | | @param | `recipient` | `ByStr20` | Address of the recipient whose balance is to increase. | | @param | `amount` | `Uint128` | Number of tokens to be minted. | @@ -112,20 +117,21 @@ transition Mint(recipient: ByStr20, amount: Uint128) | | Name | Description | Callback Parameters | | ------ | --------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `_tag` | `RecipientAcceptMint` | Dummy callback to prevent invalid recipient contract. | `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `minter` is the address of the minter, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens minted. | -| `_tag` | `MintSuccessCallBack` | Provide the sender the status of the mint. | `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `minter` is the address of the minter, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens minted. | +| `_tag` | `RecipientAcceptMint` | Dummy callback to prevent invalid recipient contract. | `token` : `Uint64`, `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `minter` is the address of the minter, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens minted. | +| `_tag` | `MintSuccessCallBack` | Provide the sender the status of the mint. | `token` : `Uint64`, `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `minter` is the address of the minter, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens minted. | **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | -------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `Minted` | Minting is successful. | `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `minter` is the address of the minter, `recipient` is the address whose balance will be increased, and `amount` is the amount of fungible tokens minted. | -| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner. | +| | Name | Description | Event Parameters | +| ------------ | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `Minted` | Minting is successful. | `token` : `Uint64`, `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `minter` is the address of the minter, `recipient` is the address whose balance will be increased, and `amount` is the amount of fungible tokens minted. | +| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner. | #### 2. Burn() (Optional) ```ocaml (* @dev: Burn existing tokens. Only contract_owner can burn. *) +(* @param token: Token ID. *) (* @param burn_account: Address of the token_owner whose balance is to decrease. *) (* @param amount: Number of tokens to be burned. *) transition Burn(burn_account: ByStr20, amount: Uint128) @@ -135,6 +141,7 @@ transition Burn(burn_account: ByStr20, amount: Uint128) | | Name | Type | Description | | ------ | -------------- | --------- | -------------------------------------------------------- | +| @param | `token` | `ByStr20` | A token ID. | | @param | `burn_account` | `ByStr20` | Address of the token_owner whose balance is to decrease. | | @param | `amount` | `Uint128` | Number of tokens to be burned. | @@ -142,71 +149,77 @@ transition Burn(burn_account: ByStr20, amount: Uint128) | | Name | Description | Callback Parameters | | ------ | --------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_tag` | `BurnSuccessCallBack` | Provide the sender the status of the burn. | `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | +| `_tag` | `BurnSuccessCallBack` | Provide the sender the status of the burn. | `token` : `Uint64`, `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | **Events/Errors:** | | Name | Description | Event Parameters | | ------------ | ------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `Burnt` | Burning is successful. | `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | -| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of token_owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the token_owner. | +| `_eventname` | `Burnt` | Burning is successful. | `token` : `Uint64`, `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | +| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of relevant owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the relevant holder. | #### 3. AuthorizeOperator() (Optional) ```ocaml (* @dev: Make an address an operator of the caller. *) +(* @param token: Token ID. *) (* @param operator: Address to be authorize as operator or *) (* Re-authorize as default_operator. Cannot be calling address. *) -transition AuthorizeOperator(operator: ByStr20) +transition AuthorizeOperator(token: Uint64, operator: ByStr20) ``` **Arguments:** | | Name | Type | Description | | ------ | ---------- | --------- | --------------------------------------------------------------------------------------------------- | +| @param | `token` | `Uint64` | Token ID | | @param | `operator` | `ByStr20` | Address to be authorize as operator or re-authorize as default_operator. Cannot be calling address. | **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | -------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `AuthorizeOperatorSuccess` | Authorizing is successful. | `authorizer`: `ByStr20` which is the caller's address, and `authorized_operator`: `ByStr20` which is the address to be authorized as an operator of the token_owner. | -| `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator. | +| | Name | Description | Event Parameters | +| ------------ | -------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `AuthorizeOperatorSuccess` | Authorizing is successful. | `token` : `Uint64` which is the token ID, `authorizer`: `ByStr20` which is the caller's address, and `authorized_operator`: `ByStr20` which is the address to be authorized as an operator of the token_owner. | +| `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator. | #### 4. RevokeOperator() (Optional) ```ocaml (* @dev: Revoke an address from being an operator or default_operator of the caller. *) +(* @param token: Token ID. *) (* @param operator: Address to be removed as operator or default_operator. *) -transition RevokeOperator(operator: ByStr20) +transition RevokeOperator(token: Uint64, operator: ByStr20) ``` **Arguments:** | | Name | Type | Description | | ------ | ---------- | --------- | -------------------------------- | +| @param | `token` | `Uint64` | Token ID | | @param | `operator` | `ByStr20` | Address to be unset as operator. | **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | ----------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `RevokeOperatorSuccess` | Revoking is successful. | `revoker`: `ByStr20` which is the caller's address, and `revoked_operator`: `ByStr20` which is the address to be removed as an operator of the token_owner. | -| `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner. | +| | Name | Description | Event Parameters | +| ------------ | ----------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `RevokeOperatorSuccess` | Revoking is successful. | `token`: `Uint64` which is the token ID, `revoker`: `ByStr20` which is the caller's address, and `revoked_operator`: `ByStr20` which is the address to be removed as an operator of the token_owner. | +| `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner. | #### 5. IncreaseAllowance() ```ocaml (* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param token: Token ID. *) (* param spender: Address of the designated approved_spender. *) (* param amount: Number of tokens to be increased as allowance for the approved_spender. *) -transition IncreaseAllowance(spender: ByStr20, amount: Uint128) +transition IncreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) ``` **Arguments:** | | Name | Type | Description | | ------ | --------- | --------- | ------------------------------------------------------------------------------- | +| @param | `token` | `Uint64` | Token ID | | @param | `spender` | `ByStr20` | Address of an approved_spender. | | @param | `amount` | `Uint128` | Number of tokens to be increased as spending allowance of the approved_spender. | @@ -214,22 +227,24 @@ transition IncreaseAllowance(spender: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `IncreasedAllowance` | Increasing of allowance of an approved_spender is successful. | `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | +| `_eventname` | `IncreasedAllowance` | Increasing of allowance of an approved_spender is successful. | `token`: `Uint64` which is the token ID, `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | | `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | #### 6. DecreaseAllowance() ```ocaml (* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param token: Token ID. *) (* param spender: Address of the designated approved_spender. *) (* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) -transition DecreaseAllowance(spender: ByStr20, amount: Uint128) +transition DecreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) ``` **Arguments:** | | Name | Type | Description | | ------ | --------- | --------- | ------------------------------------------------------------------------------- | +| @param | `token` | `Uint64` | Token ID | | @param | `spender` | `ByStr20` | Address of an approved_spender. | | @param | `amount` | `Uint128` | Number of tokens to be decreased as spending allowance of the approved_spender. | @@ -237,7 +252,7 @@ transition DecreaseAllowance(spender: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `DecreasedAllowance` | Decreasing of allowance of an approved_spender is successful. | `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | +| `_eventname` | `DecreasedAllowance` | Decreasing of allowance of an approved_spender is successful. | `token`: `Uint64` which is the token ID, `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | | `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | #### 7. Transfer() @@ -245,15 +260,17 @@ transition DecreaseAllowance(spender: ByStr20, amount: Uint128) ```ocaml (* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) (* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) +(* @param token: Token ID. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be sent. *) -transition Transfer(to: ByStr20, amount: Uint128) +transition Transfer(token: Uint64, to: ByStr20, amount: Uint128) ``` **Arguments:** | | Name | Type | Description | | ------ | -------- | --------- | ------------------------------------------------------ | +| @param | `token` | `Uint64` | Token ID. | | @param | `to` | `ByStr20` | Address of the recipient whose balance is to increase. | | @param | `amount` | `Uint128` | Amount of tokens to be sent. | @@ -261,15 +278,15 @@ transition Transfer(to: ByStr20, amount: Uint128) | | Name | Description | Callback Parameters | | ------ | ------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_tag` | `RecipientAcceptTransfer` | Dummy callback to prevent invalid recipient contract. | `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `sender` is the address of the sender, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | -| `_tag` | `TransferSuccessCallBack` | Provide the sender the status of the transfer. | `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `sender` is the address of the sender, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `RecipientAcceptTransfer` | Dummy callback to prevent invalid recipient contract. | `token` : `Uint64`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `sender` is the address of the sender, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `TransferSuccessCallBack` | Provide the sender the status of the transfer. | `token` : `Uint64`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `sender` is the address of the sender, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | ----------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `TransferSuccess` | Sending is successful. | `sender`: `ByStr20` which is the sender's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens transferred. | -| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | +| | Name | Description | Event Parameters | +| ------------ | ----------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `TransferSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `sender`: `ByStr20` which is the sender's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | #### 8. TransferFrom() @@ -279,13 +296,14 @@ transition Transfer(to: ByStr20, amount: Uint128) (* @param from: Address of the token_owner whose balance is decreased. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be transferred. *) -transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) +transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint128) ``` **Arguments:** | | Name | Type | Description | | ------ | -------- | --------- | -------------------------------------------------------- | +| @param | `token` | `Uint64` | Token ID. | | @param | `from` | `ByStr20` | Address of the token_owner whose balance is to decrease. | | @param | `to` | `ByStr20` | Address of the recipient whose balance is to increase. | | @param | `amount` | `Uint128` | Number of tokens to be transferred. | @@ -294,14 +312,14 @@ transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) | | Name | Description | Callback Parameters | | ------ | ----------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `_tag` | `RecipientAcceptTransferFrom` | Dummy callback to prevent invalid recipient contract. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | -| `_tag` | `TransferFromSuccessCallBack` | Provide the initiator the status of the transfer. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `RecipientAcceptTransferFrom` | Dummy callback to prevent invalid recipient contract. | `token`: `Uint64`, `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is te token ID, `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `TransferFromSuccessCallBack` | Provide the initiator the status of the transfer. | `token`: `Uint64`, `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is te token ID, `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | **Events:** | | Name | Description | Event Parameters | | ------------ | --------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `_eventname` | `TransferFromSuccess` | Sending is successful. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_eventname` | `TransferFromSuccess` | Sending is successful. | `token`: `Uint64`, `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | #### 9. OperatorSend() (Optional) @@ -309,6 +327,7 @@ transition TransferFrom(from: ByStr20, to: ByStr20, amount: Uint128) ```ocaml (* @dev: Moves amount tokens from token_owner to recipient. _sender must be an operator of token_owner. *) (* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param token: Token ID. *) (* @param from: Address of the token_owner whose balance is decreased. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be sent. *) @@ -319,6 +338,7 @@ transition OperatorSend(from: ByStr20, to: ByStr20, amount: Uint128) | | Name | Type | Description | | ------ | -------- | --------- | -------------------------------------------------------- | +| @param | `token` | `Uint64` | Token ID. | | @param | `from` | `ByStr20` | Address of the token_owner whose balance is to decrease. | | @param | `to` | `ByStr20` | Address of the recipient whose balance is to increase. | | @param | `amount` | `Uint128` | Amount of tokens to be sent. | @@ -327,21 +347,19 @@ transition OperatorSend(from: ByStr20, to: ByStr20, amount: Uint128) | | Name | Description | Callback Parameters | | ------ | ----------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_tag` | `RecipientAcceptOperatorSend` | Dummy callback to prevent invalid recipient contract. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an operator,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | -| `_tag` | `OperatorSendSuccessCallBack` | Provide the operator the status of the transfer. | `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `initiator` is the address of an operator,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `RecipientAcceptOperatorSend` | Dummy callback to prevent invalid recipient contract. | `token`: `Uint64`, `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `initiator` is the address of an operator, `sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | +| `_tag` | `OperatorSendSuccessCallBack` | Provide the operator the status of the transfer. | `token`: `Uint64`, `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `initiator` is the address of an operator, `sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | **Events/Errors:** | | Name | Description | Event Parameters | | ------------ | --------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `OperatorSendSuccess` | Sending is successful. | `initiator`: `ByStr20` which is the operator's address, `sender`: `ByStr20` which is the token_owner's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens to be transferred. | +| `_eventname` | `OperatorSendSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `initiator`: `ByStr20` which is the operator's address, `sender`: `ByStr20` which is the token_owner's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens to be transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred. | ## V. Existing Implementation(s) -- [ZRC2 Reference contract](../reference/FungibleToken.scilla) -- [ZRC2-Mintable Reference contract](../reference/FungibleToken-Mintable.scilla) -- [ZRC2-Operator Reference contract](../reference/FungibleToken-Operator.scilla) +- [ZRC2 to ZRC6 wrapper contract](../reference/FungibleMultoToken.scilla) To test the reference contract, simply go to the [`example`](../example) folder and run one of the JS scripts. For example, to deploy the contract, run: From d41112017641d404099f8cf1506145b4e07fd5aa Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 13:40:54 +0200 Subject: [PATCH 17/51] bug fix --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 0c2060997..14afe3968 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -1,4 +1,4 @@ -| ZRC | Title | Status | Type | Author | Created (yyyy-mm-dd) | Updated (yyyy-mm-dd) | +| ZRC | Title | Status | Type | Author | Created (yyyy-mm-dd) | | --- | ---------------------------- | ------ | -------- | ------------------------------- | -------------------- | | 2 | Standard for Multiple Tokens | Draft | Standard | Victor Porton | 2020-10-30 | From bb9e2efe79b52b0a8442305fd1dbf4acedd32f37 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 13:48:33 +0200 Subject: [PATCH 18/51] new error --- zrcs/zrc-6.md | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 14afe3968..12000f90a 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -124,8 +124,9 @@ transition Mint(token: ByStr20, recipient: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `Minted` | Minting is successful. | `token` : `Uint64`, `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `minter` is the address of the minter, `recipient` is the address whose balance will be increased, and `amount` is the amount of fungible tokens minted. | +| `_eventname` | `Minted` | Minting is successful. | `token` : `Uint64`, `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `minter` is the address of the minter, `recipient` is the address whose balance will be increased, and `amount` is the amount of fungible tokens minted. | | `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 2. Burn() (Optional) @@ -153,10 +154,11 @@ transition Burn(burn_account: ByStr20, amount: Uint128) **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | ------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `Burnt` | Burning is successful. | `token` : `Uint64`, `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | -| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of relevant owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the relevant holder. | +| | Name | Description | Event Parameters | +| ------------ | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_eventname` | `Burnt` | Burning is successful. | `token` : `Uint64`, `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | +| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of relevant owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the relevant holder. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 3. AuthorizeOperator() (Optional) @@ -181,6 +183,7 @@ transition AuthorizeOperator(token: Uint64, operator: ByStr20) | ------------ | -------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `AuthorizeOperatorSuccess` | Authorizing is successful. | `token` : `Uint64` which is the token ID, `authorizer`: `ByStr20` which is the caller's address, and `authorized_operator`: `ByStr20` which is the address to be authorized as an operator of the token_owner. | | `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 4. RevokeOperator() (Optional) @@ -204,6 +207,7 @@ transition RevokeOperator(token: Uint64, operator: ByStr20) | ------------ | ----------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `RevokeOperatorSuccess` | Revoking is successful. | `token`: `Uint64` which is the token ID, `revoker`: `ByStr20` which is the caller's address, and `revoked_operator`: `ByStr20` which is the address to be removed as an operator of the token_owner. | | `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 5. IncreaseAllowance() @@ -225,10 +229,11 @@ transition IncreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | Name | Description | Event Parameters | +| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `_eventname` | `IncreasedAllowance` | Increasing of allowance of an approved_spender is successful. | `token`: `Uint64` which is the token ID, `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | -| `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | +| `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 6. DecreaseAllowance() @@ -250,10 +255,11 @@ transition DecreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | Name | Description | Event Parameters | +| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `_eventname` | `DecreasedAllowance` | Decreasing of allowance of an approved_spender is successful. | `token`: `Uint64` which is the token ID, `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | -| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | +| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 7. Transfer() @@ -287,6 +293,7 @@ transition Transfer(token: Uint64, to: ByStr20, amount: Uint128) | ------------ | ----------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `TransferSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `sender`: `ByStr20` which is the sender's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 8. TransferFrom() @@ -317,10 +324,11 @@ transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 **Events:** -| | Name | Description | Event Parameters | -| ------------ | --------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| | Name | Description | Event Parameters | +| ------------ | --------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `TransferFromSuccess` | Sending is successful. | `token`: `Uint64`, `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | -| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 9. OperatorSend() (Optional) @@ -352,10 +360,11 @@ transition OperatorSend(from: ByStr20, to: ByStr20, amount: Uint128) **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | --------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| | Name | Description | Event Parameters | +| ------------ | --------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `OperatorSendSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `initiator`: `ByStr20` which is the operator's address, `sender`: `ByStr20` which is the token_owner's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens to be transferred. | -| `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | ## V. Existing Implementation(s) From b62eee9fb3bd047692c46f1f4ac3ad86419ff72c Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 13:51:33 +0200 Subject: [PATCH 19/51] bug fix --- zrcs/zrc-6.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 12000f90a..ae7f62efd 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -154,11 +154,10 @@ transition Burn(burn_account: ByStr20, amount: Uint128) **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `_eventname` | `Burnt` | Burning is successful. | `token` : `Uint64`, `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | -| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of relevant owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the relevant holder. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| | Name | Description | Event Parameters | +| ------------ | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `Burnt` | Burning is successful. | `token` : `Uint64`, `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | +| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of relevant owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the relevant holder.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | #### 3. AuthorizeOperator() (Optional) @@ -182,8 +181,7 @@ transition AuthorizeOperator(token: Uint64, operator: ByStr20) | | Name | Description | Event Parameters | | ------------ | -------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `AuthorizeOperatorSuccess` | Authorizing is successful. | `token` : `Uint64` which is the token ID, `authorizer`: `ByStr20` which is the caller's address, and `authorized_operator`: `ByStr20` which is the address to be authorized as an operator of the token_owner. | -| `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | #### 4. RevokeOperator() (Optional) @@ -232,8 +230,7 @@ transition IncreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `_eventname` | `IncreasedAllowance` | Increasing of allowance of an approved_spender is successful. | `token`: `Uint64` which is the token ID, `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | -| `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 6. DecreaseAllowance() From 09b52d973a1dadfe45224d8a5cc9e28a840773a1 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 13:54:54 +0200 Subject: [PATCH 20/51] bug fix --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index ae7f62efd..8d9bda2a0 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -135,7 +135,7 @@ transition Mint(token: ByStr20, recipient: ByStr20, amount: Uint128) (* @param token: Token ID. *) (* @param burn_account: Address of the token_owner whose balance is to decrease. *) (* @param amount: Number of tokens to be burned. *) -transition Burn(burn_account: ByStr20, amount: Uint128) +transition Burn(token: ByStr20, burn_account: ByStr20, amount: Uint128) ``` **Arguments:** From 204080715a68695a66acc19c26049bdeca679fa3 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:00:13 +0200 Subject: [PATCH 21/51] an additional event --- zrcs/zrc-6.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 8d9bda2a0..1abf6c1bc 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -363,7 +363,13 @@ transition OperatorSend(from: ByStr20, to: ByStr20, amount: Uint128) | `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred. | | | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | -## V. Existing Implementation(s) +## V. More events + +| | Name | Description | Event Parameters | +| ------------ | -------------- | -------------------- | ----------------------------------------------------------------------------------------- | +| `_eventname` | `CreatedToken` | A token was created. | `token_owner` : `ByStr20` who created the token, `token`: `Uint64` which is the token ID. | + +## VI. Existing Implementation(s) - [ZRC2 to ZRC6 wrapper contract](../reference/FungibleMultoToken.scilla) From 8f66969549f6d6c1ffed9eea4007b24d1dc0c441 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:01:47 +0200 Subject: [PATCH 22/51] bug fix --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 1abf6c1bc..b4d01faf0 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -336,7 +336,7 @@ transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 (* @param from: Address of the token_owner whose balance is decreased. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be sent. *) -transition OperatorSend(from: ByStr20, to: ByStr20, amount: Uint128) +transition OperatorSend(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint128) ``` **Arguments:** From 41040cac1c0c4ab1d25e69f71b35152179e0f915 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:05:36 +0200 Subject: [PATCH 23/51] remark --- zrcs/zrc-6.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index b4d01faf0..ef9200297 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -25,13 +25,13 @@ The multiple token contract specification describes: ### A. Roles -| Name | Description | -| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `contract_owner` | The owner of the contract initialized by the creator of the contract. | -| `token_owner` | A user (identified by an address) that owns tokens. | -| `approved_spender` | A user (identified by an address) that can transfer tokens on behalf of the token_owner. | -| `operator` | A user (identified by an address) that is approved to operate all tokens owned by another user (identified by another address). This role is optional. | -| `default_operator` | A special user (identified by an address) that is approved to operate all tokens owned by all users (identified by addresses). This role is optional. | +| Name | Description | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `contract_owner` | The owner of the contract initialized by the creator of the contract. | +| `token_owner` | A user (identified by an address) that owns tokens. | +| `approved_spender` | A user (identified by an address) that can transfer tokens on behalf of the token_owner. | +| `operator` | A user (identified by an address) that is approved to operate all tokens owned by another user (identified by another address). This role is optional. (Remark: we don't provide default operators per-token to save gas.) | +| `default_operator` | A special user (identified by an address) that is approved to operate all tokens owned by all users (identified by addresses). This role is optional. | ### B. Error Codes From 27c2193577175ccc38a322077cf64529f307e8cb Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:12:56 +0200 Subject: [PATCH 24/51] bug fix --- zrcs/zrc-6.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index ef9200297..65b30423d 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -55,17 +55,17 @@ The fungible token contract must define the following constants for use as error ### D. Mutable Fields -| Name | Type | Description | -| --------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `name` | `Map ByStr20 String` | The name of the tokens. | -| `symbol` | `Map ByStr20 String` | The symbol of the tokens. | -| `decimals` | `Map ByStr20 Uint32` | The number of decimal places a token can be divided by. | -| `init_supply` | `Map ByStr20 Uint128` | The initial supply of tokens when a token is created. | -| `total_supply` | `Map ByStr20 Uint128` | Total amount of tokens available. | -| `balances` | `Map ByStr20 Uint128` | Mapping between token owner to number of owned tokens. | -| `allowances` | `Map ByStr20 (Map ByStr20 Uint128)` | Mapping from token owner to approved spender address. Token owner can give an address an allowance of tokens to transfer tokens to other addresses. | -| `operators` | `Map ByStr20 (Map ByStr20 Unit)` | Mapping from token owner to designated operators. A token owner can approve an address as an operator (as per the definition of operator given above). This mapping is optional. | -| `revoked_default_operators` | `Map ByStr20 (Map ByStr20 Unit)` | Mapping from token owner to revoked default operators. Default operators are intialised by the contract owner. A token owner can revoked a default operator (as per the definition of default operator given above) at will. This mapping is optional. | +| Name | Tpe | Description | +| --------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `name` | `Map Uint64 String` | The name of the tokens. | +| `symbol` | `Map Uint64 String` | The symbol of the tokens. | +| `decimals` | `Map Uint64 Uint32` | The number of decimal places a token can be divided by. | +| `init_supply` | `Map Uint64 Uint128` | The initial supply of tokens when a token is created. | +| `total_supply` | `Map Uint64 Uint128` | Total amount of tokens available. | +| `balances` | `Map Uint64 Uint128` | Mapping between token owner to number of owned tokens. | +| `allowances` | `Map Uint64 (Map ByStr20 Uint128)` | Mapping from token owner to approved spender address. Token owner can give an address an allowance of tokens to transfer tokens to other addresses. | +| `operators` | `Map Uint64 (Map ByStr20 Unit)` | Mapping from token owner to designated operators. A token owner can approve an address as an operator (as per the definition of operator given above). This mapping is optional. | +| `revoked_default_operators` | `Map Uint64 (Map ByStr20 Unit)` | Mapping from token owner to revoked default operators. Default operators are intialised by the contract owner. A token owner can revoked a default operator (as per the definition of default operator given above) at will. This mapping is optional. | ### E. Getter Transitions From 8c8e42a90d6b36a0327a58977446805ea32c5d18 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:14:35 +0200 Subject: [PATCH 25/51] grammar --- zrcs/zrc-6.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 65b30423d..0bb0d14bd 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -173,7 +173,7 @@ transition AuthorizeOperator(token: Uint64, operator: ByStr20) | | Name | Type | Description | | ------ | ---------- | --------- | --------------------------------------------------------------------------------------------------- | -| @param | `token` | `Uint64` | Token ID | +| @param | `token` | `Uint64` | Token ID. | | @param | `operator` | `ByStr20` | Address to be authorize as operator or re-authorize as default_operator. Cannot be calling address. | **Events/Errors:** @@ -196,7 +196,7 @@ transition RevokeOperator(token: Uint64, operator: ByStr20) | | Name | Type | Description | | ------ | ---------- | --------- | -------------------------------- | -| @param | `token` | `Uint64` | Token ID | +| @param | `token` | `Uint64` | Token ID. | | @param | `operator` | `ByStr20` | Address to be unset as operator. | **Events/Errors:** @@ -221,7 +221,7 @@ transition IncreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) | | Name | Type | Description | | ------ | --------- | --------- | ------------------------------------------------------------------------------- | -| @param | `token` | `Uint64` | Token ID | +| @param | `token` | `Uint64` | Token ID. | | @param | `spender` | `ByStr20` | Address of an approved_spender. | | @param | `amount` | `Uint128` | Number of tokens to be increased as spending allowance of the approved_spender. | @@ -246,7 +246,7 @@ transition DecreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) | | Name | Type | Description | | ------ | --------- | --------- | ------------------------------------------------------------------------------- | -| @param | `token` | `Uint64` | Token ID | +| @param | `token` | `Uint64` | Token ID. | | @param | `spender` | `ByStr20` | Address of an approved_spender. | | @param | `amount` | `Uint128` | Number of tokens to be decreased as spending allowance of the approved_spender. | From a4e0b9f722f5656fa9802ac405af1d632e940b9b Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:16:16 +0200 Subject: [PATCH 26/51] bug fix --- zrcs/zrc-6.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 0bb0d14bd..09cabf768 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -289,8 +289,7 @@ transition Transfer(token: Uint64, to: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | ----------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `TransferSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `sender`: `ByStr20` which is the sender's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens transferred. | -| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 8. TransferFrom() From 7b889f9ab314792d13e8f0985637462e51773cfc Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:16:56 +0200 Subject: [PATCH 27/51] bug fix --- zrcs/zrc-6.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 09cabf768..09d570507 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -323,8 +323,7 @@ transition TransferFrom(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 | | Name | Description | Event Parameters | | ------------ | --------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `TransferFromSuccess` | Sending is successful. | `token`: `Uint64`, `initiator`: `ByStr20`, `sender` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `initiator` is the address of an approved_spender,`sender` is the address of the token_owner, `recipient` is the address of the recipient, and `amount` is the amount of fungible tokens to be transferred. | -| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 9. OperatorSend() (Optional) From 87558e89d6d992c89602581858692100f24bef4e Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:18:04 +0200 Subject: [PATCH 28/51] bug fix --- zrcs/zrc-6.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 09d570507..385e69908 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -358,8 +358,7 @@ transition OperatorSend(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 | | Name | Description | Event Parameters | | ------------ | --------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `OperatorSendSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `initiator`: `ByStr20` which is the operator's address, `sender`: `ByStr20` which is the token_owner's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens to be transferred. | -| `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | ## V. More events From eb4413128bc9bf9a28680603029328660ab4381c Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:19:26 +0200 Subject: [PATCH 29/51] formatting --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 385e69908..6661eb29e 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -142,7 +142,7 @@ transition Burn(token: ByStr20, burn_account: ByStr20, amount: Uint128) | | Name | Type | Description | | ------ | -------------- | --------- | -------------------------------------------------------- | -| @param | `token` | `ByStr20` | A token ID. | +| @param | `token` | `ByStr20` | A token ID. | | @param | `burn_account` | `ByStr20` | Address of the token_owner whose balance is to decrease. | | @param | `amount` | `Uint128` | Number of tokens to be burned. | From 211e519a6771137123387c77f5e6a567b7d0122b Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:20:10 +0200 Subject: [PATCH 30/51] bug fix --- zrcs/zrc-6.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 6661eb29e..d02d94c1e 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -204,8 +204,7 @@ transition RevokeOperator(token: Uint64, operator: ByStr20) | | Name | Description | Event Parameters | | ------------ | ----------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `RevokeOperatorSuccess` | Revoking is successful. | `token`: `Uint64` which is the token ID, `revoker`: `ByStr20` which is the caller's address, and `revoked_operator`: `ByStr20` which is the address to be removed as an operator of the token_owner. | -| `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 5. IncreaseAllowance() From 2e984cc8b5d137eae026c5852a773c0c97d7888a Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:24:25 +0200 Subject: [PATCH 31/51] bug fixes --- zrcs/zrc-6.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index d02d94c1e..b2aa17f07 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -98,7 +98,7 @@ transition IsOperatorFor(token: Uint64, token_owner: ByStr20, operator: ByStr20) #### 1. Mint() (Optional) ```ocaml -(* @dev: Mint new tokens. Only contract_owner can mint. *) +(* @dev: Mint new tokens. Only the relevant owner can mint. *) (* @param token: Token ID. *) (* @param recipient: Address of the recipient whose balance is to increase. *) (* @param amount: Number of tokens to be minted. *) @@ -131,7 +131,7 @@ transition Mint(token: ByStr20, recipient: ByStr20, amount: Uint128) #### 2. Burn() (Optional) ```ocaml -(* @dev: Burn existing tokens. Only contract_owner can burn. *) +(* @dev: Burn existing tokens. Only relevant owner can burn. *) (* @param token: Token ID. *) (* @param burn_account: Address of the token_owner whose balance is to decrease. *) (* @param amount: Number of tokens to be burned. *) @@ -157,7 +157,7 @@ transition Burn(token: ByStr20, burn_account: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `Burnt` | Burning is successful. | `token` : `Uint64`, `burner` : `ByStr20`, `burn_account`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `burner` is the address of the burner, `burn_account` is the address whose balance will be decreased, and `amount` is the amount of fungible tokens burned. | -| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the contract_owner.
- emit `CodeNoBalance` if balance of relevant owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of the relevant holder.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | +| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the relevant owner.
- emit `CodeNoBalance` if balance of token_owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of token_owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | #### 3. AuthorizeOperator() (Optional) @@ -234,10 +234,10 @@ transition IncreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) #### 6. DecreaseAllowance() ```ocaml -(* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) -(* param token: Token ID. *) -(* param spender: Address of the designated approved_spender. *) -(* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) +(* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only the token_owner allowed to invoke. *) +(* param token: Token ID. *) +(* param spender: Address of the designated approved_spender. *) +(* param amount: Number of tokens to be decreased as allowance for the approved_spender. *) transition DecreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) ``` From 2d514843989738786c8b2753644cd1b94a0efd0a Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 14:25:14 +0200 Subject: [PATCH 32/51] standard number correction --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index b2aa17f07..cc2d6edf7 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -1,6 +1,6 @@ | ZRC | Title | Status | Type | Author | Created (yyyy-mm-dd) | | --- | ---------------------------- | ------ | -------- | ------------------------------- | -------------------- | -| 2 | Standard for Multiple Tokens | Draft | Standard | Victor Porton | 2020-10-30 | +| 6 | Standard for Multiple Tokens | Draft | Standard | Victor Porton | 2020-10-30 | ## I. What are Fungible Tokens? From e53c062d4c56881e3f81ebd991dc2ccebc9973f1 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:01:59 +0200 Subject: [PATCH 33/51] multi-token operations --- zrcs/zrc-6.md | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index cc2d6edf7..493ca59ff 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -45,6 +45,7 @@ The fungible token contract must define the following constants for use as error | `CodeNotOwner` | `Int32` | `-4` | Emit when the sender is not a relevant owner. This error code is optional. | | `CodeNotApprovedOperator` | `Int32` | `-5` | Emit when caller is not an approved operator or default_operator. This error code is optional. | | `CodeTokenDoesNotExist` | `Int32` | `-6` | Emit when trying to use a non-existing token. | +| `CodeInequalLengths` | `Int32` | `-7` | Emit when argument array lengths do not match. | ### C. Immutable Variables @@ -359,6 +360,271 @@ transition OperatorSend(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 | `_eventname` | `OperatorSendSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `initiator`: `ByStr20` which is the operator's address, `sender`: `ByStr20` which is the token_owner's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens to be transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | +#### 1. MintMultiple() (Optional) + +```ocaml +(* @dev: Mint new tokens. Only the relevant owner can mint. *) +(* @param tokens: Token IDs. *) +(* @param recipients: Addresses of the recipients whose balance is to increase. *) +(* @param amounts: Numbers of tokens to be minted. *) +transition MintMultiple(tokens: List ByStr20, recipients: List ByStr20, amounts: List Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ------------ | --------- | -------------------------------------------------------------- | +| @param | `tokens` | `List ByStr20` | Token IDs. | +| @param | `recipients` | `List ByStr20` | Addresses of the recipients whose balance is to increase. | +| @param | `amounts` | `List Uint128` | Numbers of tokens to be minted. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | --------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_tag` | `RecipientAcceptMint` | Dummy callback to prevent invalid recipient contract. | `tokens` : `List Uint64`, `minter` : `ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `minter` is the address of the minter, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens minted. | +| `_tag` | `MintSuccessCallBack` | Provide the sender the status of the mint. | `tokens` : `List Uint64`, `minter` : `ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `minter` is the address of the minter, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens minted. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `Minted` | Minting is successful. | `tokens` : `Uint64`, `minter` : `ByStr20`, `recipients`: `ByStr20`, `amounts`: `Uint128`, where `tokens` are the tokens IDs, `minter` is the address of the minter, `recipients` are the addresses whose balances will be increased, and `amounts` are the amounts of fungible tokens minted. | +| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | + +#### 2. BurnMultiple() (Optional) + +```ocaml +(* @dev: Burn existing tokens. Only relevant owner can burn. *) +(* @param tokens: Tokens IDs. *) +(* @param burn_accounts: Addresses of the token_owner whose balance is to decrease. *) +(* @param amounts: Numbers of tokens to be burned. *) +transition BurnMultiple(tokens: List ByStr20, burn_accounts: List ByStr20, amounts: List Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | --------------- | -------------- | ----------------------------------------------------------- | +| @param | `tokens` | `List ByStr20` | Tokens IDs. | +| @param | `burn_accounts` | `List ByStr20` | Addresses of the token_owner whose balances is to decrease. | +| @param | `amounts` | `List Uint128` | Numbers of tokens to be burned. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | --------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_tag` | `BurnSuccessCallBack` | Provide the sender the status of the burn. | `tokens` : `List Uint64`, `burner` : `ByStr20`, `burn_accounts`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the token IDs, `burner` is the address of the burner, `burn_accounts` are the addresses whose balance will be decreased, and `amounts` are the amounts of fungible tokens burned. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `Burnt` | Burning is successful. | `tokens` : `List Uint64`, `burner` : `ByStr20`, `burn_accounts`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `burner` is the address of the burner, `burn_accounts` are the addresses whose balances will be decreased, and `amounts` are the amounts of fungible tokens burned. | +| `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the relevant owner.
- emit `CodeNoBalance` if balance of token_owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of token_owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | + +#### 3. AuthorizeOperatorMultiple() (Optional) + +```ocaml +(* @dev: Make an address an operator of the caller. *) +(* @param tokens: Tokens IDs. *) +(* @param operator: Address to be authorized as operator or *) +(* Re-authorize as default_operator. Cannot be calling address. *) +transition AuthorizeOperator(tokens: List Uint64, operator: ByStr20) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ---------- | ------------- | --------------------------------------------------------------------------------------------------- | +| @param | `token` | `List Uint64` | Tokens IDs. | +| @param | `operator` | `ByStr20` | Address to be authorize as operator or re-authorize as default_operator. Cannot be calling address. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `AuthorizeOperatorSuccess` | Authorizing is successful. | `tokens` : `List Uint64` which are the tokens IDs, `authorizer`: `ByStr20` which is the caller's address, and `authorized_operator`: `ByStr20` which is the address to be authorized as an operator of the token_owner. | +| `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | + +#### 4. RevokeOperatorMultiple() (Optional) + +```ocaml +(* @dev: Revoke an address from being an operator or default_operator of the caller. *) +(* @param tokens: Tokens IDs. *) +(* @param operator: Address to be removed as operator or default_operator. *) +transition RevokeOperatorMultiple(tokens: List Uint64, operator: ByStr20) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ---------- | ------------- | -------------------------------- | +| @param | `tokens` | `List Uint64` | Tokens IDs. | +| @param | `operator` | `ByStr20` | Address to be unset as operator. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | ----------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `RevokeOperatorSuccess` | Revoking is successful. | `tokens`: `List Uint64` which are the tokens IDs, `revoker`: `ByStr20` which is the caller's address, and `revoked_operator`: `ByStr20` which is the address to be removed as an operator of the token_owner. | +| `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | + +#### 5. IncreaseAllowanceMultiple() + +```ocaml +(* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) +(* param tokens: Tokens IDs. *) +(* param spender: Address of the designated approved_spender. *) +(* param amounts: Number of tokens to be increased as allowance for the approved_spender. *) +transition IncreaseAllowance(tokens: List Uint64, spender: ByStr20, amounts: List Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | --------- | -------------- | -------------------------------------------------------------------------------- | +| @param | `tokens` | `List Uint64` | Tokens IDs. | +| @param | `spender` | `ByStr20` | Address of an approved_spender. | +| @param | `amounts` | `List Uint128` | Numbers of tokens to be increased as spending allowance of the approved_spender. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_eventname` | `IncreasedAllowance` | Increasing of allowance of an approved_spender is successful. | `tokens`: `List Uint64` which are the tokens IDs, `token_owners`: `List ByStr20` which are the addressese the token_owner's, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowances of the approved_spender for the token_owner's. | +| `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | + +#### 6. DecreaseAllowance() + +```ocaml +(* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only the token_owner allowed to invoke. *) +(* param tokens: Tokens *) +(* param spender: Address of the designated approved_spender. *) +(* param amounts: Numbers of tokens to be decreased as allowance for the approved_spender. *) +transition DecreaseAllowance(tokens: List Uint64, spender: ByStr20, amounts: List Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | --------- | -------------- | -------------------------------------------------------------------------------- | +| @param | `tokens` | `List Uint64` | Tokens IDs. | +| @param | `spender` | `ByStr20` | Address of an approved_spender. | +| @param | `amounts` | `List Uint128` | Numbers of tokens to be decreased as spending allowance of the approved_spender. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_eventname` | `DecreasedAllowance` | Decreasing of allowance of an approved_spender is successful. | `tokens`: `List Uint64` which are the tokens IDs, `token_owners`: `List ByStr20` which are the addresses the token_owner's, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowances` are the new spending allowances of the approved_spender for the token_owner's. | +| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | +| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | + +#### 7. Transfer() + +```ocaml +(* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) +(* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) +(* @param tokens: Tokens IDs. *) +(* @param tos: Addresses of the recipients whose balance is increased. *) +(* @param amounts: Amounts of tokens to be sent. *) +transition Transfer(token: List Uint64, to: List ByStr20, amount: List Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | -------- | --------- | -------------------------------------------------------------- | +| @param | `token` | `List Uint64` | Tokens IDs. | +| @param | `to` | `List ByStr20` | Addresses of the recipients whose balance is to increase. | +| @param | `amount` | `List Uint128` | Amounts of tokens to be sent. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_tag` | `RecipientAcceptTransfer` | Dummy callback to prevent invalid recipient contract. | `tokens` : `List Uint64`, `sender` : `ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `sender` is the address of the sender, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | +| `_tag` | `TransferSuccessCallBack` | Provide the sender the status of the transfer. | `tokens` : `List Uint64`, `sender` : `ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `sender` is the address of the sender, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | ----------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `TransferSuccess` | Sending is successful. | `tokens`: `List Uint64` which is the token ID, `sender`: `ByStr20` which is the sender's address, `recipients`: `List ByStr20` which is the recipient's address, and `amounts`: `List Uint128` which is the amount of fungible tokens transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | + +#### 8. TransferFromMultiple() + +```ocaml +(* @dev: Move a given amount of tokens from one address to another using the allowance mechanism. The caller must be an approved_spender. *) +(* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param tokens: Token IDs. *) +(* @param froms: Addresses of the token_owner's whose balance is decreased. *) +(* @param tos: Addresses of the recipients whose balance is increased. *) +(* @param amounts: Amounts of tokens to be transferred. *) +transition TransferFromMultiple(tokens: List Uint64, froms: List ByStr20, tos: List ByStr20, amounts: List Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | --------- | --------- | ----------------------------------------------------------------- | +| @param | `tokens` | `List Uint64` | Tokens IDs. | +| @param | `froms` | `List ByStr20` | Addresses of the token_owner's whose balance is to decrease. | +| @param | `tos` | `List ByStr20` | Addresses of the recipients whose balance is to increase. | +| @param | `amounts` | `List Uint128` | Numbers of tokens to be transferred. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ----------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `_tag` | `RecipientAcceptTransferFrom` | Dummy callback to prevent invalid recipient contract. | `tokens`: `List Uint64`, `initiator`: `ByStr20`, `senders` : `List ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are te tokens ID,s `initiator` is the address of an approved_spender, `senders` are the addresses of the token_owner's, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | +| `_tag` | `TransferFromSuccessCallBack` | Provide the initiator the status of the transfer. | `tokens`: `List Uint64`, `initiator`: `ByStr20`, `senders` : `List ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are te tokens ID,s `initiator` is the address of an approved_spender, `senders` are the addresses of the token_owner's, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | + +**Events:** + +| | Name | Description | Event Parameters | +| ------------ | --------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `TransferFromSuccess` | Sending is successful. | `tokens`: `List Uint64`, `initiator`: `ByStr20`, `senders` : `List ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `initiator` is the address of an approved_spender, `senders` are the addresses of the token_owner's, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | + +#### 9. OperatorSendMultple() (Optional) + +```ocaml +(* @dev: Moves amount tokens from token_owner to recipient. _sender must be an operator of token_owner. *) +(* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param tokens: Tokens IDs. *) +(* @param froms: Addresses of the token_owner's whose balance is decreased. *) +(* @param tos: Addresses of the recipients whose balance is increased. *) +(* @param amounts: Amounts of tokens to be sent. *) +transition OperatorSend(tokens: List Uint64, from: List ByStr20, to: List ByStr20, amount: List Uint128) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | -------- | --------- | ------------------------------------------------------------------ | +| @param | `tokens` | `List Uint64` | Tokens IDs. | +| @param | `froms` | `List ByStr20` | Addresses of the token_owner\s whose balance is to decrease. | +| @param | `tos` | `List ByStr20` | Addresses of the recipients whose balance is to increase. | +| @param | `amousnt` | `List Uint128` | Amounts of tokens to be sent. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ----------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_tag` | `RecipientAcceptOperatorSend` | Dummy callback to prevent invalid recipient contract. | `tokens`: `List Uint64`, `initiator`: `ByStr20`, `senders` : `List ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `initiator` is the address of an operator, `senders` are the addresses of the token_owner's, `recipients` are the address of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | +| `_tag` | `OperatorSendSuccessCallBack` | Provide the operator the status of the transfer. | `tokens`: `List Uint64`, `initiator`: `ByStr20`, `senders` : `List ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `initiator` is the address of an operator, `senders` are the addresses of the token_owner's, `recipients` are the address of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | + +**Events/Errors:** + +| | Name | Description | Event Parameters | +| ------------ | --------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `OperatorSendSuccess` | Sending is successful. | `tokens`: `List Uint64` which are the tokens ID, `initiator`: `ByStr20` which is the operator's address, `senders`: `List ByStr20` which are the token_owner's addresses, `recipients`: `List ByStr20` which are the recipient's addresses, and `amounts`: `List Uint128` which are the amounts of fungible tokens to be transferred. | +| `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner's
- emit `CodeInsufficientFunds` if the balance of the token_owner's is lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | + ## V. More events | | Name | Description | Event Parameters | From a78681dfeb6c989652c479fccf77f14918ca07f9 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:02:39 +0200 Subject: [PATCH 34/51] bug fix --- zrcs/zrc-6.md | 1 + 1 file changed, 1 insertion(+) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 493ca59ff..0121ad20c 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -296,6 +296,7 @@ transition Transfer(token: Uint64, to: ByStr20, amount: Uint128) ```ocaml (* @dev: Move a given amount of tokens from one address to another using the allowance mechanism. The caller must be an approved_spender. *) (* @dev: Balance of recipient will increase. Balance of token_owner will decrease. *) +(* @param token: Token ID. *) (* @param from: Address of the token_owner whose balance is decreased. *) (* @param to: Address of the recipient whose balance is increased. *) (* @param amount: Amount of tokens to be transferred. *) From 3bd8a816f7541c27afada7fa100ddc2e34191c47 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:04:58 +0200 Subject: [PATCH 35/51] bug fixes --- zrcs/zrc-6.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 0121ad20c..05292f825 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -361,7 +361,7 @@ transition OperatorSend(token: Uint64, from: ByStr20, to: ByStr20, amount: Uint1 | `_eventname` | `OperatorSendSuccess` | Sending is successful. | `token`: `Uint64` which is the token ID, `initiator`: `ByStr20` which is the operator's address, `sender`: `ByStr20` which is the token_owner's address, `recipient`: `ByStr20` which is the recipient's address, and `amount`: `Uint128` which is the amount of fungible tokens to be transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner
- emit `CodeInsufficientFunds` if the balance of the token_owner is lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | -#### 1. MintMultiple() (Optional) +#### 10. MintMultiple() (Optional) ```ocaml (* @dev: Mint new tokens. Only the relevant owner can mint. *) @@ -394,7 +394,7 @@ transition MintMultiple(tokens: List ByStr20, recipients: List ByStr20, amounts: | `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner. | | | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | -#### 2. BurnMultiple() (Optional) +#### 11. BurnMultiple() (Optional) ```ocaml (* @dev: Burn existing tokens. Only relevant owner can burn. *) @@ -425,14 +425,14 @@ transition BurnMultiple(tokens: List ByStr20, burn_accounts: List ByStr20, amoun | `_eventname` | `Burnt` | Burning is successful. | `tokens` : `List Uint64`, `burner` : `ByStr20`, `burn_accounts`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `burner` is the address of the burner, `burn_accounts` are the addresses whose balances will be decreased, and `amounts` are the amounts of fungible tokens burned. | | `_eventname` | `Error` | Burning is not successful. | - emit `CodeNotOwner` if the transition is not called by the relevant owner.
- emit `CodeNoBalance` if balance of token_owner does not exists.
- emit `CodeInsufficientFunds` if the amount to be burned is more than the balance of token_owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | -#### 3. AuthorizeOperatorMultiple() (Optional) +#### 12. AuthorizeOperatorMultiple() (Optional) ```ocaml (* @dev: Make an address an operator of the caller. *) (* @param tokens: Tokens IDs. *) (* @param operator: Address to be authorized as operator or *) (* Re-authorize as default_operator. Cannot be calling address. *) -transition AuthorizeOperator(tokens: List Uint64, operator: ByStr20) +transition AuthorizeOperatorMultiple(tokens: List Uint64, operator: ByStr20) ``` **Arguments:** @@ -449,7 +449,7 @@ transition AuthorizeOperator(tokens: List Uint64, operator: ByStr20) | `_eventname` | `AuthorizeOperatorSuccess` | Authorizing is successful. | `tokens` : `List Uint64` which are the tokens IDs, `authorizer`: `ByStr20` which is the caller's address, and `authorized_operator`: `ByStr20` which is the address to be authorized as an operator of the token_owner. | | `_eventname` | `Error` | Authorizing is not successful. | - emit `CodeIsSender` if the user is trying to authorize himself as an operator.
- emit `CodeTokenDoesNotExist` if the token ID does not exist. | -#### 4. RevokeOperatorMultiple() (Optional) +#### 13. RevokeOperatorMultiple() (Optional) ```ocaml (* @dev: Revoke an address from being an operator or default_operator of the caller. *) @@ -472,14 +472,14 @@ transition RevokeOperatorMultiple(tokens: List Uint64, operator: ByStr20) | `_eventname` | `RevokeOperatorSuccess` | Revoking is successful. | `tokens`: `List Uint64` which are the tokens IDs, `revoker`: `ByStr20` which is the caller's address, and `revoked_operator`: `ByStr20` which is the address to be removed as an operator of the token_owner. | | `_eventname` | `Error` | Revoking is not successful. | - emit `CodeNotApprovedOperator` if the specified address is not an existing operator or default_operator of the token_owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | -#### 5. IncreaseAllowanceMultiple() +#### 14. IncreaseAllowanceMultiple() ```ocaml (* @dev: Increase the allowance of an approved_spender over the caller tokens. Only token_owner allowed to invoke. *) (* param tokens: Tokens IDs. *) (* param spender: Address of the designated approved_spender. *) (* param amounts: Number of tokens to be increased as allowance for the approved_spender. *) -transition IncreaseAllowance(tokens: List Uint64, spender: ByStr20, amounts: List Uint128) +transition IncreaseAllowanceMultiple(tokens: List Uint64, spender: ByStr20, amounts: List Uint128) ``` **Arguments:** @@ -497,14 +497,14 @@ transition IncreaseAllowance(tokens: List Uint64, spender: ByStr20, amounts: Lis | `_eventname` | `IncreasedAllowance` | Increasing of allowance of an approved_spender is successful. | `tokens`: `List Uint64` which are the tokens IDs, `token_owners`: `List ByStr20` which are the addressese the token_owner's, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowances of the approved_spender for the token_owner's. | | `_eventname` | `Error` | Increasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | -#### 6. DecreaseAllowance() +#### 15. DecreaseAllowanceMultiple() ```ocaml (* @dev: Decrease the allowance of an approved_spender over the caller tokens. Only the token_owner allowed to invoke. *) (* param tokens: Tokens *) (* param spender: Address of the designated approved_spender. *) (* param amounts: Numbers of tokens to be decreased as allowance for the approved_spender. *) -transition DecreaseAllowance(tokens: List Uint64, spender: ByStr20, amounts: List Uint128) +transition DecreaseAllowanceMultiple(tokens: List Uint64, spender: ByStr20, amounts: List Uint128) ``` **Arguments:** @@ -523,7 +523,7 @@ transition DecreaseAllowance(tokens: List Uint64, spender: ByStr20, amounts: Lis | `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | | | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | -#### 7. Transfer() +#### 16. TransferMultiple() ```ocaml (* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) @@ -531,7 +531,7 @@ transition DecreaseAllowance(tokens: List Uint64, spender: ByStr20, amounts: Lis (* @param tokens: Tokens IDs. *) (* @param tos: Addresses of the recipients whose balance is increased. *) (* @param amounts: Amounts of tokens to be sent. *) -transition Transfer(token: List Uint64, to: List ByStr20, amount: List Uint128) +transition TransferMultiple(token: List Uint64, to: List ByStr20, amount: List Uint128) ``` **Arguments:** @@ -556,7 +556,7 @@ transition Transfer(token: List Uint64, to: List ByStr20, amount: List Uint128) | `_eventname` | `TransferSuccess` | Sending is successful. | `tokens`: `List Uint64` which is the token ID, `sender`: `ByStr20` which is the sender's address, `recipients`: `List ByStr20` which is the recipient's address, and `amounts`: `List Uint128` which is the amount of fungible tokens transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | -#### 8. TransferFromMultiple() +#### 17. TransferFromMultiple() ```ocaml (* @dev: Move a given amount of tokens from one address to another using the allowance mechanism. The caller must be an approved_spender. *) @@ -591,7 +591,7 @@ transition TransferFromMultiple(tokens: List Uint64, froms: List ByStr20, tos: L | `_eventname` | `TransferFromSuccess` | Sending is successful. | `tokens`: `List Uint64`, `initiator`: `ByStr20`, `senders` : `List ByStr20`, `recipients`: `List ByStr20`, `amounts`: `List Uint128`, where `tokens` are the tokens IDs, `initiator` is the address of an approved_spender, `senders` are the addresses of the token_owner's, `recipients` are the addresses of the recipients, and `amounts` are the amounts of fungible tokens to be transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeInsufficientAllowance` if the allowance of approved_spender is lesser than the specified amount that is to be transferred.
- emit `CodeInsufficientFunds` if the balance of the token_owner lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | -#### 9. OperatorSendMultple() (Optional) +#### 18. OperatorSendMultiple() (Optional) ```ocaml (* @dev: Moves amount tokens from token_owner to recipient. _sender must be an operator of token_owner. *) @@ -600,7 +600,7 @@ transition TransferFromMultiple(tokens: List Uint64, froms: List ByStr20, tos: L (* @param froms: Addresses of the token_owner's whose balance is decreased. *) (* @param tos: Addresses of the recipients whose balance is increased. *) (* @param amounts: Amounts of tokens to be sent. *) -transition OperatorSend(tokens: List Uint64, from: List ByStr20, to: List ByStr20, amount: List Uint128) +transition OperatorSendMultiple(tokens: List Uint64, from: List ByStr20, to: List ByStr20, amount: List Uint128) ``` **Arguments:** From e1ecab059f61e23768ac1abac93b352b51fe1e93 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:15:26 +0200 Subject: [PATCH 36/51] bug fix --- zrcs/zrc-6.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 05292f825..dd180b1eb 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -126,8 +126,7 @@ transition Mint(token: ByStr20, recipient: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `Minted` | Minting is successful. | `token` : `Uint64`, `minter` : `ByStr20`, `recipient`: `ByStr20`, `amount`: `Uint128`, where `token` is the token ID, `minter` is the address of the minter, `recipient` is the address whose balance will be increased, and `amount` is the amount of fungible tokens minted. | -| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 2. Burn() (Optional) From ae7652c61ab9e1b1add67ee49741b1d8a42d6557 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:16:14 +0200 Subject: [PATCH 37/51] bug fix --- zrcs/zrc-6.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index dd180b1eb..ebd0cf427 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -254,8 +254,7 @@ transition DecreaseAllowance(token: Uint64, spender: ByStr20, amount: Uint128) | | Name | Description | Event Parameters | | ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `_eventname` | `DecreasedAllowance` | Decreasing of allowance of an approved_spender is successful. | `token`: `Uint64` which is the token ID, `token_owner`: `ByStr20` which is the address the token_owner, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowance` is the new spending allowance of the approved_spender for the token_owner. | -| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 7. Transfer() From 09ce4b7ec8cfaae67235feece2ab9ec823109c1c Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:17:21 +0200 Subject: [PATCH 38/51] bug fix --- zrcs/zrc-6.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index ebd0cf427..014dd7664 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -386,11 +386,10 @@ transition MintMultiple(tokens: List ByStr20, recipients: List ByStr20, amounts: **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `_eventname` | `Minted` | Minting is successful. | `tokens` : `Uint64`, `minter` : `ByStr20`, `recipients`: `ByStr20`, `amounts`: `Uint128`, where `tokens` are the tokens IDs, `minter` is the address of the minter, `recipients` are the addresses whose balances will be increased, and `amounts` are the amounts of fungible tokens minted. | -| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| | Name | Description | Event Parameters | +| ------------ | -------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `_eventname` | `Minted` | Minting is successful. | `tokens` : `Uint64`, `minter` : `ByStr20`, `recipients`: `ByStr20`, `amounts`: `Uint128`, where `tokens` are the tokens IDs, `minter` is the address of the minter, `recipients` are the addresses whose balances will be increased, and `amounts` are the amounts of fungible tokens minted. | +| `_eventname` | `Error` | Minting is not successful. | - emit `CodeNotOwner` if the transition is not called by the appropriate owner.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 11. BurnMultiple() (Optional) From aedce8552b77cf2e38c054b05341c6b9ea67061b Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:18:46 +0200 Subject: [PATCH 39/51] bug fix --- zrcs/zrc-6.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 014dd7664..f134d1ec6 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -514,11 +514,10 @@ transition DecreaseAllowanceMultiple(tokens: List Uint64, spender: ByStr20, amou **Events/Errors:** -| | Name | Description | Event Parameters | -| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| | Name | Description | Event Parameters | +| ------------ | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_eventname` | `DecreasedAllowance` | Decreasing of allowance of an approved_spender is successful. | `tokens`: `List Uint64` which are the tokens IDs, `token_owners`: `List ByStr20` which are the addresses the token_owner's, `spender`: `ByStr20` which is the address of a approved_spender of the token_owner, and `new_allowances` are the new spending allowances of the approved_spender for the token_owner's. | -| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender. | -| | | | - emit `CodeTokenDoesNotExist` if the token ID does not exist | +| `_eventname` | `Error` | Decreasing of allowance is not successful. | - emit `CodeIsSelf` if the user is trying to authorize himself as an approved_spender.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | #### 16. TransferMultiple() From fdeaa2450f775d968a86bab6077779d276a87986 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 15:31:35 +0200 Subject: [PATCH 40/51] title fix --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index f134d1ec6..de6c5c521 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -2,7 +2,7 @@ | --- | ---------------------------- | ------ | -------- | ------------------------------- | -------------------- | | 6 | Standard for Multiple Tokens | Draft | Standard | Victor Porton | 2020-10-30 | -## I. What are Fungible Tokens? +## I. What are Multiple Tokens? This standard allows a contract to "contain" both fungible (like ZRC-2) and non-fungible (like ZRC-1) tokens. Up to 2**64 tokens per single contract are supported. From d90a306d2ad7900aff8eb5a0b9c71c239b7621df Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:16:14 +0200 Subject: [PATCH 41/51] ZRC --- zrcs/zrc-6.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index de6c5c521..146353282 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -622,12 +622,16 @@ transition OperatorSendMultiple(tokens: List Uint64, from: List ByStr20, to: Lis | `_eventname` | `OperatorSendSuccess` | Sending is successful. | `tokens`: `List Uint64` which are the tokens ID, `initiator`: `ByStr20` which is the operator's address, `senders`: `List ByStr20` which are the token_owner's addresses, `recipients`: `List ByStr20` which are the recipient's addresses, and `amounts`: `List Uint128` which are the amounts of fungible tokens to be transferred. | | `_eventname` | `Error` | Sending is not successful. | - emit `CodeNotApprovedOperator` if sender is not an approved operator for the token_owner's
- emit `CodeInsufficientFunds` if the balance of the token_owner's is lesser than the specified amount that is to be transferred.
- emit `CodeTokenDoesNotExist` if the token ID does not exist | -## V. More events +## V. More Events | | Name | Description | Event Parameters | | ------------ | -------------- | -------------------- | ----------------------------------------------------------------------------------------- | | `_eventname` | `CreatedToken` | A token was created. | `token_owner` : `ByStr20` who created the token, `token`: `Uint64` which is the token ID. | +## VI. Misc Notes + +This standard is deliberately not interoperable with ZRC-1, because ZRC-1 restricts minting tokens to the addresses that are keys of `minters` mapping. It is not an acceptable requirement for this standard because sometimes it's necessary to allow everyone to mint new tokens. + ## VI. Existing Implementation(s) - [ZRC2 to ZRC6 wrapper contract](../reference/FungibleMultoToken.scilla) From bd2a32ce1c7920a64ffc3660358f189825256788 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:24:21 +0200 Subject: [PATCH 42/51] BalancesMultiple --- zrcs/zrc-6.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 146353282..82e924ade 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -94,6 +94,28 @@ transition IsOperatorFor(token: Uint64, token_owner: ByStr20, operator: ByStr20) | ------ | ----------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `_tag` | `IsOperatorForCallBack` | Provide the sender a callback if specified address is indeed an approved operator of specified token_owner. | `token` : `Uint64`, `token_owner` : `ByStr20`, `operator`: `ByStr20`, where `token_owner` is the address of the token_owner, `operator` is the address of the approved operator. | +#### 2. BalancesMultiple() (Optional) + +```ocaml +(* @dev: Get balances of several tokens. *) +(* @param tokens: Tokens IDs. *) +(* @param token_owner: Address of a token_owner. *) +transition BalancesMultiple(tokens: List Uint64, token_owner: ByStr20) +``` + +**Arguments:** + +| | Name | Type | Description | +| ------ | ------------- | ------------- | --------------------------------------- | +| @param | `tokens` | `List Uint64` | A token ID. | +| @param | `token_owner` | `ByStr20` | An address of a particular token_owner. | + +**Messages sent:** + +| | Name | Description | Callback Parameters | +| ------ | ------------------ | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| `_tag` | `BalancesMultiple` | Provide the sender a callback wit token balances. | `balances` : `List Uint128` is the list of balances correspondign to tokens for a given token_owner. | + ### F. Interface Transitions #### 1. Mint() (Optional) From 6bdd50be3fbefcdb4ce0863d954f2e599538b8af Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:25:17 +0200 Subject: [PATCH 43/51] typo --- zrcs/zrc-6.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 82e924ade..7f358ad2a 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -112,9 +112,9 @@ transition BalancesMultiple(tokens: List Uint64, token_owner: ByStr20) **Messages sent:** -| | Name | Description | Callback Parameters | -| ------ | ------------------ | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| `_tag` | `BalancesMultiple` | Provide the sender a callback wit token balances. | `balances` : `List Uint128` is the list of balances correspondign to tokens for a given token_owner. | +| | Name | Description | Callback Parameters | +| ------ | ------------------ | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `_tag` | `BalancesMultiple` | Provide the sender a callback with token balances. | `balances` : `List Uint128` is the list of balances correspondign to tokens for a given token_owner. | ### F. Interface Transitions From c21e83fabfe1d5d854b0cc3c3303c2f92d37be9e Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:26:14 +0200 Subject: [PATCH 44/51] formatting --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 7f358ad2a..891e6a4b1 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -122,7 +122,7 @@ transition BalancesMultiple(tokens: List Uint64, token_owner: ByStr20) ```ocaml (* @dev: Mint new tokens. Only the relevant owner can mint. *) -(* @param token: Token ID. *) +(* @param token: Token ID. *) (* @param recipient: Address of the recipient whose balance is to increase. *) (* @param amount: Number of tokens to be minted. *) transition Mint(token: ByStr20, recipient: ByStr20, amount: Uint128) From 046ffcd6df8952c7c2e85a94ae141eb2b88e090a Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:28:13 +0200 Subject: [PATCH 45/51] typo --- zrcs/zrc-6.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 891e6a4b1..3790afbd4 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -549,16 +549,16 @@ transition DecreaseAllowanceMultiple(tokens: List Uint64, spender: ByStr20, amou (* @param tokens: Tokens IDs. *) (* @param tos: Addresses of the recipients whose balance is increased. *) (* @param amounts: Amounts of tokens to be sent. *) -transition TransferMultiple(token: List Uint64, to: List ByStr20, amount: List Uint128) +transition TransferMultiple(tokens: List Uint64, tos: List ByStr20, amounts: List Uint128) ``` **Arguments:** | | Name | Type | Description | | ------ | -------- | --------- | -------------------------------------------------------------- | -| @param | `token` | `List Uint64` | Tokens IDs. | -| @param | `to` | `List ByStr20` | Addresses of the recipients whose balance is to increase. | -| @param | `amount` | `List Uint128` | Amounts of tokens to be sent. | +| @param | `tokens` | `List Uint64` | Tokens IDs. | +| @param | `tos` | `List ByStr20` | Addresses of the recipients whose balance is to increase. | +| @param | `amounts` | `List Uint128` | Amounts of tokens to be sent. | **Messages sent:** From 8e121dabc572c6a4f2fa4608d98cf21ab42c9c8a Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:28:50 +0200 Subject: [PATCH 46/51] typo --- zrcs/zrc-6.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 3790afbd4..145c0b3d1 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -546,9 +546,9 @@ transition DecreaseAllowanceMultiple(tokens: List Uint64, spender: ByStr20, amou ```ocaml (* @dev: Moves an amount tokens from _sender to the recipient. Used by token_owner. *) (* @dev: Balance of recipient will increase. Balance of _sender will decrease. *) -(* @param tokens: Tokens IDs. *) -(* @param tos: Addresses of the recipients whose balance is increased. *) -(* @param amounts: Amounts of tokens to be sent. *) +(* @param tokens: Tokens IDs. *) +(* @param tos: Addresses of the recipients whose balance is increased. *) +(* @param amounts: Amounts of tokens to be sent. *) transition TransferMultiple(tokens: List Uint64, tos: List ByStr20, amounts: List Uint128) ``` From 5ecdc3d5394bda3ec1cdfc53ae9e214e8079deac Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:29:43 +0200 Subject: [PATCH 47/51] typos --- zrcs/zrc-6.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 145c0b3d1..92faa4d49 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -618,7 +618,7 @@ transition TransferFromMultiple(tokens: List Uint64, froms: List ByStr20, tos: L (* @param froms: Addresses of the token_owner's whose balance is decreased. *) (* @param tos: Addresses of the recipients whose balance is increased. *) (* @param amounts: Amounts of tokens to be sent. *) -transition OperatorSendMultiple(tokens: List Uint64, from: List ByStr20, to: List ByStr20, amount: List Uint128) +transition OperatorSendMultiple(tokens: List Uint64, froms: List ByStr20, tos: List ByStr20, amounts: List Uint128) ``` **Arguments:** @@ -628,7 +628,7 @@ transition OperatorSendMultiple(tokens: List Uint64, from: List ByStr20, to: Lis | @param | `tokens` | `List Uint64` | Tokens IDs. | | @param | `froms` | `List ByStr20` | Addresses of the token_owner\s whose balance is to decrease. | | @param | `tos` | `List ByStr20` | Addresses of the recipients whose balance is to increase. | -| @param | `amousnt` | `List Uint128` | Amounts of tokens to be sent. | +| @param | `amounts` | `List Uint128` | Amounts of tokens to be sent. | **Messages sent:** From 94fe9a2e28a9f47b23810b261156676695604c36 Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:34:29 +0200 Subject: [PATCH 48/51] typo --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index 92faa4d49..f803e843b 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -458,7 +458,7 @@ transition AuthorizeOperatorMultiple(tokens: List Uint64, operator: ByStr20) | | Name | Type | Description | | ------ | ---------- | ------------- | --------------------------------------------------------------------------------------------------- | -| @param | `token` | `List Uint64` | Tokens IDs. | +| @param | `tokens` | `List Uint64` | Tokens IDs. | | @param | `operator` | `ByStr20` | Address to be authorize as operator or re-authorize as default_operator. Cannot be calling address. | **Events/Errors:** From 47d1148ee1061e7a98691cc26500ae7b54ceafeb Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:38:42 +0200 Subject: [PATCH 49/51] typos --- zrcs/zrc-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrcs/zrc-6.md b/zrcs/zrc-6.md index f803e843b..bc0a21800 100644 --- a/zrcs/zrc-6.md +++ b/zrcs/zrc-6.md @@ -656,7 +656,7 @@ This standard is deliberately not interoperable with ZRC-1, because ZRC-1 restri ## VI. Existing Implementation(s) -- [ZRC2 to ZRC6 wrapper contract](../reference/FungibleMultoToken.scilla) +- [ZRC-2 to ZRC-6 wrapper contract](../reference/FungibleMultoToken.scilla) To test the reference contract, simply go to the [`example`](../example) folder and run one of the JS scripts. For example, to deploy the contract, run: From 09ca052e656b737b08c64cb75f7bb2f121fe538c Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:41:50 +0200 Subject: [PATCH 50/51] contract address updated --- example/zrc6/store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/zrc6/store.js b/example/zrc6/store.js index 2c6d7b06a..f9e63b598 100644 --- a/example/zrc6/store.js +++ b/example/zrc6/store.js @@ -22,7 +22,7 @@ async function main() { const ftAddrHuman = "509ae6e5d91cee3c6571dcd04aa08288a29d563a"; - const mtAddrHuman = "9b80a12a68989575b7fd4b82a6dabee468ab9d92"; + const mtAddrHuman = "e3aa085f045abb2102520b3678d54dd551a04b08"; const ftAddr = toBech32Address(ftAddrHuman); const mtAddr = toBech32Address(mtAddrHuman); const receiptAddrHuman = "BFe2445408C51CD8Ee6727541195b02c891109ee"; From 1eb010bd960b19892ae1cc4126bb2e20f55466ab Mon Sep 17 00:00:00 2001 From: Victor Porton Date: Fri, 30 Oct 2020 16:48:21 +0200 Subject: [PATCH 51/51] test bug fix --- example/zrc6/store.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/example/zrc6/store.js b/example/zrc6/store.js index f9e63b598..da2f270b3 100644 --- a/example/zrc6/store.js +++ b/example/zrc6/store.js @@ -38,6 +38,21 @@ async function main() { vname: 'zrc2_contract', type: 'ByStr20', value: '0x'+ftAddrHuman, + }, + { + vname: 'newName', + type: 'String', + value: "A token", + }, + { + vname: 'newSymbol', + type: 'String', + value: "SYM", + }, + { + vname: 'newDecimals', + type: 'Uint32', + value: "18", } ], { @@ -48,6 +63,7 @@ async function main() { gasLimit: Long.fromNumber(10000), } ); + console.log(JSON.stringify(createTokenCallTx, null, 4)); console.log(JSON.stringify(createTokenCallTx.receipt, null, 4)); const tokenId = createTokenCallTx.receipt.event_logs.filter(e => e._eventname === "CreatedToken")[0] .params.filter(p => p.vname === "token")[0].value;