From 7666714e8205a2f37b6f32cda4584068cceb94c6 Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 24 Jul 2019 14:49:46 +0300 Subject: [PATCH 01/97] introduce the file structure, layout and part of the content sanitized all content existing at this point order the sub-items clean up the index.md files, we will introduce them if needed where needed later. Clean up the *action-reference.md files, they will be generated later and add more layout content, and content. add more content and clean up compile and deploy can't be put together for each individual contract cause right now to compile you have to compile them all but to deploy you can deploy each one individually. clean up not suitable phrase. --- docs.json | 22 ++ docs/eosio.bios/deploy.md | 12 + docs/eosio.bios/introduction.md | 30 +++ docs/eosio.msig/deploy.md | 12 + ...a-multisig-transaction-with-eosio.msig.md} | 41 ++-- docs/eosio.msig/introduction.md | 19 ++ docs/eosio.system/deploy.md | 12 + docs/eosio.system/guides/how-to-buy-ram.md | 20 ++ docs/eosio.system/guides/how-to-stake.md | 47 ++++ docs/eosio.system/guides/how-to-vote.md | 12 + .../upgrading-the-eosio.system-contract.md | 209 ++++++++++++++++++ docs/eosio.system/introduction.md | 65 ++++++ docs/eosio.token/deploy.md | 12 + ...w-to-create,-issue-and-transfer-a-token.md | 152 +++++++++++++ docs/eosio.token/introduction.md | 21 ++ docs/eosio.wrap/deploy.md | 12 + .../guides/how-to-use-eosio.wrap.md} | 0 docs/eosio.wrap/introduction.md | 12 + docs/introduction.md | 52 +++++ docs2.json | 21 ++ 20 files changed, 757 insertions(+), 26 deletions(-) create mode 100644 docs.json create mode 100644 docs/eosio.bios/deploy.md create mode 100644 docs/eosio.bios/introduction.md create mode 100644 docs/eosio.msig/deploy.md rename docs/{eosio.msig.md => eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md} (89%) create mode 100644 docs/eosio.msig/introduction.md create mode 100644 docs/eosio.system/deploy.md create mode 100644 docs/eosio.system/guides/how-to-buy-ram.md create mode 100644 docs/eosio.system/guides/how-to-stake.md create mode 100644 docs/eosio.system/guides/how-to-vote.md create mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md create mode 100644 docs/eosio.system/introduction.md create mode 100644 docs/eosio.token/deploy.md create mode 100644 docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md create mode 100644 docs/eosio.token/introduction.md create mode 100644 docs/eosio.wrap/deploy.md rename docs/{eosio.wrap.md => eosio.wrap/guides/how-to-use-eosio.wrap.md} (100%) create mode 100644 docs/eosio.wrap/introduction.md create mode 100644 docs/introduction.md create mode 100644 docs2.json diff --git a/docs.json b/docs.json new file mode 100644 index 000000000..f6a7a50c1 --- /dev/null +++ b/docs.json @@ -0,0 +1,22 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "output": "00_eosio.token", + "INPUT": "eosio.token" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md new file mode 100644 index 000000000..57a5923b1 --- /dev/null +++ b/docs/eosio.bios/deploy.md @@ -0,0 +1,12 @@ +## Steps deploy eosio.bios contract + +In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerbios` + +``` +cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios +``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md new file mode 100644 index 000000000..fc31c0c77 --- /dev/null +++ b/docs/eosio.bios/introduction.md @@ -0,0 +1,30 @@ +## Introducing eosio.bios contract + +The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. + +The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. + +|Action name|Action description| +|---|---| +|setpriv|Set privilege status for an account.| +|setalimits|Set the resource limits of an account| +|setglimits|Not implemented yet.| +|setprods|Set a new list of active producers, that is, a new producers' schedule.| +|setparams|Set the blockchain parameters.| +|reqauth|Check if an account has authorization to access the current action.| +|setabi|Set the abi for a contract identified by an account name.| + +The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. + +Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: + +|Action name|Description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md new file mode 100644 index 000000000..d5f027d88 --- /dev/null +++ b/docs/eosio.msig/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.msig contract + +In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testermsig` + +``` +cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig +``` \ No newline at end of file diff --git a/docs/eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 89% rename from docs/eosio.msig.md rename to docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md index 2006a468c..f68dff871 100644 --- a/docs/eosio.msig.md +++ b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -1,16 +1,14 @@ -eosio.msig examples -------------------- +## eosio.msig examples -Cleos usage example for issuing tokens. ---------------------------------------- +### Cleos usage example for issuing tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' is the issuer of SYS token. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester @@ -18,8 +16,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -60,8 +57,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -69,8 +65,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user initiates execution: +#### First user initiates execution: ```` $ cleos multisig exec tester test -p tester @@ -79,16 +74,15 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e ```` -Cleos usage example for transferring tokens. -------------------------------------------- +### Cleos usage example for transferring tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' has at least 1.1000 SYS token balance. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester @@ -96,8 +90,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -139,8 +132,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -148,8 +140,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user check account balance before executing the proposed transaction +#### First user check account balance before executing the proposed transaction ```` $ cleos get account tester ... @@ -160,8 +151,7 @@ SYS balances: total: 4.0487 SYS ```` - -First user initiates execution of proposed transaction: +#### First user initiates execution of proposed transaction: ```` $ cleos multisig exec tester test -p tester @@ -169,8 +159,7 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e # eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} ```` - -First user can check account balance, it should be increased by 1.0000 SYS +#### First user can check account balance, it should be increased by 1.0000 SYS ```` $ cleos get account tester ... diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md new file mode 100644 index 000000000..8fea80569 --- /dev/null +++ b/docs/eosio.msig/introduction.md @@ -0,0 +1,19 @@ +## Introducing eosio.msig contract + +The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. + +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +- first you create a transaction json file, +- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, +- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, +- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. + +These are the actions implemented and publicly exposed by the `eosio.msig` contract: +|Action name|Action description| +|---|---| +|propose|Creates a proposal containing one transaction.| +|approve|Approves an existing proposal.| +|unapprove|Revokes an existing proposal.| +|cancel|Cancels an existing proposal.| +|exec|Allows an account to execute a proposal.| +|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md new file mode 100644 index 000000000..13703abdf --- /dev/null +++ b/docs/eosio.system/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.system contract + +In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testersystem` + +``` +cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md new file mode 100644 index 000000000..19c83a374 --- /dev/null +++ b/docs/eosio.system/guides/how-to-buy-ram.md @@ -0,0 +1,20 @@ +## How buy RAM + +### What RAM is + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### How to buy RAM + +To check the amount of RAM for an account eostutorial1: +``` +cleos get account eostutorial1 +``` + +Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: +``` +cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md new file mode 100644 index 000000000..fb0a5e318 --- /dev/null +++ b/docs/eosio.system/guides/how-to-stake.md @@ -0,0 +1,47 @@ +## How to stake + +### What staking is + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. + +### Staking tokens for CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active +``` + +### Staking tokens for Bandwidth + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active +``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md new file mode 100644 index 000000000..7ebb62f76 --- /dev/null +++ b/docs/eosio.system/guides/how-to-vote.md @@ -0,0 +1,12 @@ +## How to vote + +### What voting is + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +### How to vote + +To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. +``` +cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md new file mode 100644 index 000000000..2bd712fb4 --- /dev/null +++ b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md @@ -0,0 +1,209 @@ +## Upgrading the system contract + +### Indirect method using eosio.msig contract + +Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. + +So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). + +The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. + +The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. + +For now, it is recommended to use the direct method to upgrade the system contract. + +### Direct method (avoids using eosio.msig contract) + +Each of the top 21 block producers should do the following: + +1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): + +``` +$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio +code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 +saving wast to original_system_contract.wast +saving abi to original_system_contract.abi +``` + +2. Generate the unsigned transaction which upgrades the system contract: + +``` +$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json +``` + +The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): + +``` +{ + "expiration": "2018-06-15T22:17:10", + "ref_block_num": 4552, + "ref_block_prefix": 511016679, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], +``` + +and the last few lines should be: + +``` + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: + +3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. + +4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. + +Then each of the top 21 block producers should do the following: + +5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: + +``` +$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json +2,4c2,4 +< "expiration": "2018-06-15T22:17:10", +< "ref_block_num": 4552, +< "ref_block_prefix": 511016679, +--- +> "expiration": "2018-06-15T21:20:39", +> "ref_block_num": 4972, +> "ref_block_prefix": 195390844, +``` + +6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. + +First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. + +Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): + +``` +$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 +private key: "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" + ], + "context_free_data": [] +} +``` + +Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. + +The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. + +When the lead producer collects 15 producer signatures, the lead producer should do the following: + +7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: + +``` +$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 + "transaction_extensions": [], + "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", + "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", + "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", + "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", + "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", + "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", + "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", + "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", + "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", + "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", + "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", + "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", + "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", + "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", + "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" + ], + "context_free_data": [] +} +``` + +8. Push the signed transaction to the blockchain: + +``` +$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json +{ + "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "processed": { + "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "receipt": { + "status": "executed", + "cpu_usage_us": 4909, + "net_usage_words": 15124 + }, + "elapsed": 4909, + "net_usage": 120992, + "scheduled": false, + "action_traces": [{ +... +``` + +If you get an error message like the following: + +``` +Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations +Ensure that you have the related private keys inside your wallet and your wallet is unlocked. +``` + +That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. + +If you get an error message like the following: + +``` +Error 3090002: irrelevant signature included +Please remove the unnecessary signature from your transaction! +``` + +That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. + +If you get an error message like the following: + +``` +Error 3040006: Transaction Expiration Too Far +Please decrease the expiration time of your transaction! +``` + +That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. + +If you get an error message like the following: + +``` +Error 3040005: Expired Transaction +Please increase the expiration time of your transaction! +``` + +That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. + +9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: + +``` +$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio +code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 +saving wast to new_system_contract.wast +saving abi to new_system_contract.abi +$ diff original_system_contract.abi new_system_contract.abi +584,592d583 +< },{ +< "name": "deferred_trx_id", +< "type": "uint32" +< },{ +< "name": "last_unstake_time", +< "type": "time_point_sec" +< },{ +< "name": "unstaking", +< "type": "asset" +``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md new file mode 100644 index 000000000..1ca3ca049 --- /dev/null +++ b/docs/eosio.system/introduction.md @@ -0,0 +1,65 @@ +## Introducing eosio.system contract + +The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: +- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. +- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. +- Users can buy and sell RAM at a market-determined price. +- Users can bid on premium names. +- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. + +The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + +|Action name|Action description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setabi|Allows for updates of the contract ABI of an account.| +|setcode|Allows for updates of the contract code of an account.| +|init|Initializes the system contract for a version and a symbol.| +|setram|Set the ram supply.| +|setramrate|Set the ram increase rate.| +|setparams|Set the blockchain parameters.| +|setpriv|Set privilege status for an account (turn it on/off).| +|setalimits|Set the resource limits of an account.| +|setacctram|Set the RAM limits of an account.| +|setacctnet|Set the NET limits of an account.| +|setacctcpu|Set the CPU limits of an account.| +|rmvproducer|Deactivates a producer by name, if not found asserts.| +|updtrevision|Updates the current revision.| +|bidname|Allows an account to place a bid for a name.| +|bidrefund|Allows an account to get back the amount it bid so far on a name.| +|deposit|Deposits core tokens to user REX fund.| +|withdraw|Withdraws core tokens from user REX fund.| +|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| +|unstaketorex|Use staked core tokens to buy REX.| +|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| +|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| +|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| +|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| +|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| +|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| +|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| +|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| +|updaterex|Updates REX owner vote weight to current value of held REX tokens.| +|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| +|mvtosavings|Moves a specified amount of REX to savings bucket.| +|mvfrsavings|Moves a specified amount of REX from savings bucket.| +|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| +|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| +|buyrambytes|Increases receiver's ram in quantity of bytes provided.| +|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| +|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| +|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| +|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| +|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| +|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| +|unregprod|Deactivate the block producer with specified account.| +|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| +|regproxy|Set specified account as proxy.| +|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| +|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md new file mode 100644 index 000000000..5f341b639 --- /dev/null +++ b/docs/eosio.token/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.token contract + +In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testertoken` + +``` +cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken +``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md new file mode 100644 index 000000000..59dc04512 --- /dev/null +++ b/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md @@ -0,0 +1,152 @@ +TO DO: use this: +https://dash.readme.io/project/eosio-home/v2.3.8/docs/token-contract +(don't use below link cause it is deprecated) +https://dash.readme.io/project/eosio-cpp/v1.6/docs/quick-start-token + +## How to create, issue and transfer a token + + +## Step 1: Obtain Contract Source + +Navigate to your contracts directory. + +```text +cd CONTRACTS_DIR +``` +Pull the source + +```text +git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +``` +This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. + + +```text +cd eosio.contracts/eosio.token +``` + +## Step 2: Create Account for Contract +Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. +[[info]] +| +You may have to unlock your wallet first! + + +```shell +cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +``` + +## Step 3: Compile the Contract + + +```shell +eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen +``` + +## Step 4: Deploy the Token Contract + + +```shell +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +``` + +Result +```shell +Reading WASM from ... +Publishing contract... +executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us +# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... +# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... +warning: transaction executed locally, but may not be confirmed by the network yet ] +``` + +## Step 5: Create the Token +To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. + +Below is the concise way to call this method, using positional arguments: + +```shell +cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +An alternate approach uses named arguments: + +```shell +cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. + +## Step 6: Issue Tokens +The issuer can issue new tokens to the "alice" account created earlier. + +```text +cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +``` + +Result +```shell +executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles +# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> issue +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> transfer +# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +``` +This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. + +Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. + +To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. + +```shell +cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j +``` + +## Step 7: Transfer Tokens +Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. + +```shell +cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +``` + +Result +```text +executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles +# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +>> transfer +# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +``` +Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) + +```shell +cleos get currency balance eosio.token bob SYS +``` + + +```text +25.00 SYS +``` +Check "alice's" balance, notice that tokens were deducted from the account + +```shell +cleos get currency balance eosio.token alice SYS +``` + + +```text +75.00 SYS +``` +Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md new file mode 100644 index 000000000..dcde42fd5 --- /dev/null +++ b/docs/eosio.token/introduction.md @@ -0,0 +1,21 @@ +## Introducing eosio.token contract + +The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. + +These are the public actions the `eosio.token` contract is implementing: +|Action name|Action description| +|---|---| +|create|Allows an account to create a token in a given supply amount.| +|issue|This action issues to an account a specific quantity of tokens.| +|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| +|close|This action is the opposite for `open` action, it closes the specified account for specified token.| +|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| +|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| + +The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. + +The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). + +The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. + +Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md new file mode 100644 index 000000000..bad4e3bb6 --- /dev/null +++ b/docs/eosio.wrap/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.wrap contract + +In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerwrap` + +``` +cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap +``` \ No newline at end of file diff --git a/docs/eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md similarity index 100% rename from docs/eosio.wrap.md rename to docs/eosio.wrap/guides/how-to-use-eosio.wrap.md diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md new file mode 100644 index 000000000..db4adc63e --- /dev/null +++ b/docs/eosio.wrap/introduction.md @@ -0,0 +1,12 @@ +## Introducing eosio.wrap contract + +The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. + +It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. + +However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. + +The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. + +Why is it easier for governance actions to be executed via this contract? +The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 000000000..226ce05e3 --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,52 @@ +## About System Contracts + +The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. + +Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. + +## System contracts, system accounts, priviledged accounts + +At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. + +As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: +|Account|Priviledged|Has contract|Description| +|---|---|---|---| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| +|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.names|No|No|The account which is holding funds from namespace auctions.| +|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| +|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| +|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| +|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| +|eosio.saving|No|No|The account which holds the 4% of network inflation.| +|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| +|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| + +## How to compile the eosio.contracts + +To compile the eosio.contracts execute the following commands. + +On all platforms except macOS: +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$( nproc ) +cd .. +``` + +For macOS +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$(sysctl -n hw.ncpu) +cd .. +``` \ No newline at end of file diff --git a/docs2.json b/docs2.json new file mode 100644 index 000000000..c009574b5 --- /dev/null +++ b/docs2.json @@ -0,0 +1,21 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "INPUT": "eosio.bios eosio.system eosio.msig eosio.token eosio.wrap" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file From cb63f5667955de310a2df32769f2bfd6b11f24c4 Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 24 Jul 2019 14:49:46 +0300 Subject: [PATCH 02/97] introduce the file structure, layout and part of the content sanitized all content existing at this point order the sub-items clean up the index.md files, we will introduce them if needed where needed later. Clean up the *action-reference.md files, they will be generated later and add more layout content, and content. add more content and clean up compile and deploy can't be put together for each individual contract cause right now to compile you have to compile them all but to deploy you can deploy each one individually. clean up not suitable phrase. clean up a leftover TO DO. punctuation marks are not allowed in file names by gatsby introduce a second version for content layout, this one is more compact, better structured in relation with "Reference" section which can be only one at the root, we can not have a "Reference" section for each eosio.contract separately Restructure a little bit the introduction. --- docs.json | 22 + docs/eosio.bios/deploy.md | 12 + docs/eosio.bios/introduction.md | 30 + docs/eosio.msig/deploy.md | 12 + ...a-multisig-transaction-with-eosio.msig.md} | 41 +- docs/eosio.msig/introduction.md | 19 + docs/eosio.system/deploy.md | 12 + docs/eosio.system/guides/how-to-buy-ram.md | 20 + docs/eosio.system/guides/how-to-stake.md | 47 + docs/eosio.system/guides/how-to-vote.md | 12 + .../upgrading-the-eosio.system-contract.md | 209 +++++ docs/eosio.system/introduction.md | 65 ++ docs/eosio.token/deploy.md | 12 + ...ow-to-create-issue-and-transfer-a-token.md | 146 +++ docs/eosio.token/introduction.md | 21 + docs/eosio.wrap/deploy.md | 12 + .../guides/how-to-use-eosio.wrap.md} | 0 docs/eosio.wrap/introduction.md | 12 + docs/introduction.md | 52 ++ docs2.json | 21 + docs_v2/01_introduction.md | 186 ++++ docs_v2/02_compile-and-deploy.md | 55 ++ .../01_upgrading-the-eosio.system-contract.md | 209 +++++ docs_v2/03_guides/02_how-to-buy-ram.md | 20 + docs_v2/03_guides/03_how-to-stake.md | 47 + docs_v2/03_guides/04_how-to-vote.md | 12 + ...ow-to-create-issue-and-transfer-a-token.md | 146 +++ ...-a-multisig-transaction-with-eosio.msig.md | 171 ++++ docs_v2/03_guides/07_how-to-use-eosio.wrap.md | 874 ++++++++++++++++++ 29 files changed, 2471 insertions(+), 26 deletions(-) create mode 100644 docs.json create mode 100644 docs/eosio.bios/deploy.md create mode 100644 docs/eosio.bios/introduction.md create mode 100644 docs/eosio.msig/deploy.md rename docs/{eosio.msig.md => eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md} (89%) create mode 100644 docs/eosio.msig/introduction.md create mode 100644 docs/eosio.system/deploy.md create mode 100644 docs/eosio.system/guides/how-to-buy-ram.md create mode 100644 docs/eosio.system/guides/how-to-stake.md create mode 100644 docs/eosio.system/guides/how-to-vote.md create mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md create mode 100644 docs/eosio.system/introduction.md create mode 100644 docs/eosio.token/deploy.md create mode 100644 docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md create mode 100644 docs/eosio.token/introduction.md create mode 100644 docs/eosio.wrap/deploy.md rename docs/{eosio.wrap.md => eosio.wrap/guides/how-to-use-eosio.wrap.md} (100%) create mode 100644 docs/eosio.wrap/introduction.md create mode 100644 docs/introduction.md create mode 100644 docs2.json create mode 100644 docs_v2/01_introduction.md create mode 100644 docs_v2/02_compile-and-deploy.md create mode 100644 docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md create mode 100644 docs_v2/03_guides/02_how-to-buy-ram.md create mode 100644 docs_v2/03_guides/03_how-to-stake.md create mode 100644 docs_v2/03_guides/04_how-to-vote.md create mode 100644 docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md create mode 100644 docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md create mode 100644 docs_v2/03_guides/07_how-to-use-eosio.wrap.md diff --git a/docs.json b/docs.json new file mode 100644 index 000000000..f6a7a50c1 --- /dev/null +++ b/docs.json @@ -0,0 +1,22 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "output": "00_eosio.token", + "INPUT": "eosio.token" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md new file mode 100644 index 000000000..57a5923b1 --- /dev/null +++ b/docs/eosio.bios/deploy.md @@ -0,0 +1,12 @@ +## Steps deploy eosio.bios contract + +In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerbios` + +``` +cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios +``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md new file mode 100644 index 000000000..fc31c0c77 --- /dev/null +++ b/docs/eosio.bios/introduction.md @@ -0,0 +1,30 @@ +## Introducing eosio.bios contract + +The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. + +The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. + +|Action name|Action description| +|---|---| +|setpriv|Set privilege status for an account.| +|setalimits|Set the resource limits of an account| +|setglimits|Not implemented yet.| +|setprods|Set a new list of active producers, that is, a new producers' schedule.| +|setparams|Set the blockchain parameters.| +|reqauth|Check if an account has authorization to access the current action.| +|setabi|Set the abi for a contract identified by an account name.| + +The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. + +Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: + +|Action name|Description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md new file mode 100644 index 000000000..d5f027d88 --- /dev/null +++ b/docs/eosio.msig/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.msig contract + +In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testermsig` + +``` +cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig +``` \ No newline at end of file diff --git a/docs/eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 89% rename from docs/eosio.msig.md rename to docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md index 2006a468c..f68dff871 100644 --- a/docs/eosio.msig.md +++ b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -1,16 +1,14 @@ -eosio.msig examples -------------------- +## eosio.msig examples -Cleos usage example for issuing tokens. ---------------------------------------- +### Cleos usage example for issuing tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' is the issuer of SYS token. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester @@ -18,8 +16,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -60,8 +57,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -69,8 +65,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user initiates execution: +#### First user initiates execution: ```` $ cleos multisig exec tester test -p tester @@ -79,16 +74,15 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e ```` -Cleos usage example for transferring tokens. -------------------------------------------- +### Cleos usage example for transferring tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' has at least 1.1000 SYS token balance. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester @@ -96,8 +90,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -139,8 +132,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -148,8 +140,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user check account balance before executing the proposed transaction +#### First user check account balance before executing the proposed transaction ```` $ cleos get account tester ... @@ -160,8 +151,7 @@ SYS balances: total: 4.0487 SYS ```` - -First user initiates execution of proposed transaction: +#### First user initiates execution of proposed transaction: ```` $ cleos multisig exec tester test -p tester @@ -169,8 +159,7 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e # eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} ```` - -First user can check account balance, it should be increased by 1.0000 SYS +#### First user can check account balance, it should be increased by 1.0000 SYS ```` $ cleos get account tester ... diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md new file mode 100644 index 000000000..8fea80569 --- /dev/null +++ b/docs/eosio.msig/introduction.md @@ -0,0 +1,19 @@ +## Introducing eosio.msig contract + +The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. + +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +- first you create a transaction json file, +- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, +- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, +- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. + +These are the actions implemented and publicly exposed by the `eosio.msig` contract: +|Action name|Action description| +|---|---| +|propose|Creates a proposal containing one transaction.| +|approve|Approves an existing proposal.| +|unapprove|Revokes an existing proposal.| +|cancel|Cancels an existing proposal.| +|exec|Allows an account to execute a proposal.| +|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md new file mode 100644 index 000000000..13703abdf --- /dev/null +++ b/docs/eosio.system/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.system contract + +In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testersystem` + +``` +cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md new file mode 100644 index 000000000..19c83a374 --- /dev/null +++ b/docs/eosio.system/guides/how-to-buy-ram.md @@ -0,0 +1,20 @@ +## How buy RAM + +### What RAM is + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### How to buy RAM + +To check the amount of RAM for an account eostutorial1: +``` +cleos get account eostutorial1 +``` + +Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: +``` +cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md new file mode 100644 index 000000000..fb0a5e318 --- /dev/null +++ b/docs/eosio.system/guides/how-to-stake.md @@ -0,0 +1,47 @@ +## How to stake + +### What staking is + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. + +### Staking tokens for CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active +``` + +### Staking tokens for Bandwidth + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active +``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md new file mode 100644 index 000000000..7ebb62f76 --- /dev/null +++ b/docs/eosio.system/guides/how-to-vote.md @@ -0,0 +1,12 @@ +## How to vote + +### What voting is + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +### How to vote + +To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. +``` +cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md new file mode 100644 index 000000000..2bd712fb4 --- /dev/null +++ b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md @@ -0,0 +1,209 @@ +## Upgrading the system contract + +### Indirect method using eosio.msig contract + +Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. + +So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). + +The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. + +The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. + +For now, it is recommended to use the direct method to upgrade the system contract. + +### Direct method (avoids using eosio.msig contract) + +Each of the top 21 block producers should do the following: + +1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): + +``` +$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio +code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 +saving wast to original_system_contract.wast +saving abi to original_system_contract.abi +``` + +2. Generate the unsigned transaction which upgrades the system contract: + +``` +$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json +``` + +The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): + +``` +{ + "expiration": "2018-06-15T22:17:10", + "ref_block_num": 4552, + "ref_block_prefix": 511016679, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], +``` + +and the last few lines should be: + +``` + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: + +3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. + +4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. + +Then each of the top 21 block producers should do the following: + +5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: + +``` +$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json +2,4c2,4 +< "expiration": "2018-06-15T22:17:10", +< "ref_block_num": 4552, +< "ref_block_prefix": 511016679, +--- +> "expiration": "2018-06-15T21:20:39", +> "ref_block_num": 4972, +> "ref_block_prefix": 195390844, +``` + +6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. + +First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. + +Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): + +``` +$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 +private key: "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" + ], + "context_free_data": [] +} +``` + +Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. + +The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. + +When the lead producer collects 15 producer signatures, the lead producer should do the following: + +7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: + +``` +$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 + "transaction_extensions": [], + "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", + "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", + "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", + "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", + "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", + "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", + "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", + "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", + "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", + "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", + "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", + "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", + "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", + "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", + "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" + ], + "context_free_data": [] +} +``` + +8. Push the signed transaction to the blockchain: + +``` +$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json +{ + "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "processed": { + "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "receipt": { + "status": "executed", + "cpu_usage_us": 4909, + "net_usage_words": 15124 + }, + "elapsed": 4909, + "net_usage": 120992, + "scheduled": false, + "action_traces": [{ +... +``` + +If you get an error message like the following: + +``` +Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations +Ensure that you have the related private keys inside your wallet and your wallet is unlocked. +``` + +That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. + +If you get an error message like the following: + +``` +Error 3090002: irrelevant signature included +Please remove the unnecessary signature from your transaction! +``` + +That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. + +If you get an error message like the following: + +``` +Error 3040006: Transaction Expiration Too Far +Please decrease the expiration time of your transaction! +``` + +That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. + +If you get an error message like the following: + +``` +Error 3040005: Expired Transaction +Please increase the expiration time of your transaction! +``` + +That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. + +9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: + +``` +$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio +code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 +saving wast to new_system_contract.wast +saving abi to new_system_contract.abi +$ diff original_system_contract.abi new_system_contract.abi +584,592d583 +< },{ +< "name": "deferred_trx_id", +< "type": "uint32" +< },{ +< "name": "last_unstake_time", +< "type": "time_point_sec" +< },{ +< "name": "unstaking", +< "type": "asset" +``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md new file mode 100644 index 000000000..1ca3ca049 --- /dev/null +++ b/docs/eosio.system/introduction.md @@ -0,0 +1,65 @@ +## Introducing eosio.system contract + +The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: +- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. +- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. +- Users can buy and sell RAM at a market-determined price. +- Users can bid on premium names. +- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. + +The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + +|Action name|Action description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setabi|Allows for updates of the contract ABI of an account.| +|setcode|Allows for updates of the contract code of an account.| +|init|Initializes the system contract for a version and a symbol.| +|setram|Set the ram supply.| +|setramrate|Set the ram increase rate.| +|setparams|Set the blockchain parameters.| +|setpriv|Set privilege status for an account (turn it on/off).| +|setalimits|Set the resource limits of an account.| +|setacctram|Set the RAM limits of an account.| +|setacctnet|Set the NET limits of an account.| +|setacctcpu|Set the CPU limits of an account.| +|rmvproducer|Deactivates a producer by name, if not found asserts.| +|updtrevision|Updates the current revision.| +|bidname|Allows an account to place a bid for a name.| +|bidrefund|Allows an account to get back the amount it bid so far on a name.| +|deposit|Deposits core tokens to user REX fund.| +|withdraw|Withdraws core tokens from user REX fund.| +|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| +|unstaketorex|Use staked core tokens to buy REX.| +|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| +|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| +|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| +|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| +|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| +|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| +|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| +|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| +|updaterex|Updates REX owner vote weight to current value of held REX tokens.| +|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| +|mvtosavings|Moves a specified amount of REX to savings bucket.| +|mvfrsavings|Moves a specified amount of REX from savings bucket.| +|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| +|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| +|buyrambytes|Increases receiver's ram in quantity of bytes provided.| +|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| +|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| +|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| +|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| +|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| +|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| +|unregprod|Deactivate the block producer with specified account.| +|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| +|regproxy|Set specified account as proxy.| +|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| +|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md new file mode 100644 index 000000000..5f341b639 --- /dev/null +++ b/docs/eosio.token/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.token contract + +In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testertoken` + +``` +cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken +``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md new file mode 100644 index 000000000..3592f0592 --- /dev/null +++ b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md @@ -0,0 +1,146 @@ +## How to create, issue and transfer a token + +## Step 1: Obtain Contract Source + +Navigate to your contracts directory. + +```text +cd CONTRACTS_DIR +``` +Pull the source + +```text +git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +``` +This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. + + +```text +cd eosio.contracts/eosio.token +``` + +## Step 2: Create Account for Contract +Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. +[[info]] +| +You may have to unlock your wallet first! + + +```shell +cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +``` + +## Step 3: Compile the Contract + + +```shell +eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen +``` + +## Step 4: Deploy the Token Contract + + +```shell +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +``` + +Result +```shell +Reading WASM from ... +Publishing contract... +executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us +# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... +# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... +warning: transaction executed locally, but may not be confirmed by the network yet ] +``` + +## Step 5: Create the Token +To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. + +Below is the concise way to call this method, using positional arguments: + +```shell +cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +An alternate approach uses named arguments: + +```shell +cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. + +## Step 6: Issue Tokens +The issuer can issue new tokens to the "alice" account created earlier. + +```text +cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +``` + +Result +```shell +executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles +# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> issue +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> transfer +# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +``` +This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. + +Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. + +To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. + +```shell +cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j +``` + +## Step 7: Transfer Tokens +Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. + +```shell +cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +``` + +Result +```text +executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles +# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +>> transfer +# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +``` +Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) + +```shell +cleos get currency balance eosio.token bob SYS +``` + + +```text +25.00 SYS +``` +Check "alice's" balance, notice that tokens were deducted from the account + +```shell +cleos get currency balance eosio.token alice SYS +``` + + +```text +75.00 SYS +``` +Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md new file mode 100644 index 000000000..dcde42fd5 --- /dev/null +++ b/docs/eosio.token/introduction.md @@ -0,0 +1,21 @@ +## Introducing eosio.token contract + +The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. + +These are the public actions the `eosio.token` contract is implementing: +|Action name|Action description| +|---|---| +|create|Allows an account to create a token in a given supply amount.| +|issue|This action issues to an account a specific quantity of tokens.| +|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| +|close|This action is the opposite for `open` action, it closes the specified account for specified token.| +|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| +|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| + +The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. + +The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). + +The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. + +Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md new file mode 100644 index 000000000..bad4e3bb6 --- /dev/null +++ b/docs/eosio.wrap/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.wrap contract + +In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerwrap` + +``` +cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap +``` \ No newline at end of file diff --git a/docs/eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md similarity index 100% rename from docs/eosio.wrap.md rename to docs/eosio.wrap/guides/how-to-use-eosio.wrap.md diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md new file mode 100644 index 000000000..db4adc63e --- /dev/null +++ b/docs/eosio.wrap/introduction.md @@ -0,0 +1,12 @@ +## Introducing eosio.wrap contract + +The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. + +It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. + +However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. + +The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. + +Why is it easier for governance actions to be executed via this contract? +The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 000000000..226ce05e3 --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,52 @@ +## About System Contracts + +The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. + +Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. + +## System contracts, system accounts, priviledged accounts + +At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. + +As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: +|Account|Priviledged|Has contract|Description| +|---|---|---|---| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| +|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.names|No|No|The account which is holding funds from namespace auctions.| +|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| +|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| +|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| +|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| +|eosio.saving|No|No|The account which holds the 4% of network inflation.| +|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| +|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| + +## How to compile the eosio.contracts + +To compile the eosio.contracts execute the following commands. + +On all platforms except macOS: +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$( nproc ) +cd .. +``` + +For macOS +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$(sysctl -n hw.ncpu) +cd .. +``` \ No newline at end of file diff --git a/docs2.json b/docs2.json new file mode 100644 index 000000000..c009574b5 --- /dev/null +++ b/docs2.json @@ -0,0 +1,21 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "INPUT": "eosio.bios eosio.system eosio.msig eosio.token eosio.wrap" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file diff --git a/docs_v2/01_introduction.md b/docs_v2/01_introduction.md new file mode 100644 index 000000000..b29008924 --- /dev/null +++ b/docs_v2/01_introduction.md @@ -0,0 +1,186 @@ +# About System Contracts + +The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. + +Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. + +## System contracts, system accounts, priviledged accounts + +At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. + +As you just learned the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: + +|Account|Priviledged|Has contract|Description| +|---|---|---|---| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| +|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.names|No|No|The account which is holding funds from namespace auctions.| +|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| +|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| +|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| +|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| +|eosio.saving|No|No|The account which holds the 4% of network inflation.| +|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| +|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| + +# System contracts defined in eosio.contracts + +1. [eosio.bios](#eosio.bios-system-contract) +2. [eosio.system](#eosio.system-system-contract) +3. [eosio.msig](#eosio.msig-system-contract) +4. [eosio.token](#eosio.token-system-contract) +5. [eosio.wrap](#eosio.wrap-system-contract) + +## eosio.bios system contract + +The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. + +The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. + +|Action name|Action description| +|---|---| +|setpriv|Set privilege status for an account.| +|setalimits|Set the resource limits of an account| +|setglimits|Not implemented yet.| +|setprods|Set a new list of active producers, that is, a new producers' schedule.| +|setparams|Set the blockchain parameters.| +|reqauth|Check if an account has authorization to access the current action.| +|setabi|Set the abi for a contract identified by an account name.| + +The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. + +Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: + +|Action name|Description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setcode|Allows for update of the contract code of an account.| + +## eosio.system system contract + +The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: +- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. +- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. +- Users can buy and sell RAM at a market-determined price. +- Users can bid on premium names. +- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. + +The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + +|Action name|Action description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setabi|Allows for updates of the contract ABI of an account.| +|setcode|Allows for updates of the contract code of an account.| +|init|Initializes the system contract for a version and a symbol.| +|setram|Set the ram supply.| +|setramrate|Set the ram increase rate.| +|setparams|Set the blockchain parameters.| +|setpriv|Set privilege status for an account (turn it on/off).| +|setalimits|Set the resource limits of an account.| +|setacctram|Set the RAM limits of an account.| +|setacctnet|Set the NET limits of an account.| +|setacctcpu|Set the CPU limits of an account.| +|rmvproducer|Deactivates a producer by name, if not found asserts.| +|updtrevision|Updates the current revision.| +|bidname|Allows an account to place a bid for a name.| +|bidrefund|Allows an account to get back the amount it bid so far on a name.| +|deposit|Deposits core tokens to user REX fund.| +|withdraw|Withdraws core tokens from user REX fund.| +|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| +|unstaketorex|Use staked core tokens to buy REX.| +|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| +|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| +|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| +|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| +|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| +|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| +|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| +|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| +|updaterex|Updates REX owner vote weight to current value of held REX tokens.| +|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| +|mvtosavings|Moves a specified amount of REX to savings bucket.| +|mvfrsavings|Moves a specified amount of REX from savings bucket.| +|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| +|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| +|buyrambytes|Increases receiver's ram in quantity of bytes provided.| +|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| +|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| +|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| +|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| +|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| +|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| +|unregprod|Deactivate the block producer with specified account.| +|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| +|regproxy|Set specified account as proxy.| +|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| +|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| + +## eosio.msig system contract + +The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. + +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +- first you create a transaction json file, +- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, +- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, +- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. + +These are the actions implemented and publicly exposed by the `eosio.msig` contract: +|Action name|Action description| +|---|---| +|propose|Creates a proposal containing one transaction.| +|approve|Approves an existing proposal.| +|unapprove|Revokes an existing proposal.| +|cancel|Cancels an existing proposal.| +|exec|Allows an account to execute a proposal.| +|invalidate|Invalidate proposal.| + +## eosio.token system contract + +The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. + +These are the public actions the `eosio.token` contract is implementing: +|Action name|Action description| +|---|---| +|create|Allows an account to create a token in a given supply amount.| +|issue|This action issues to an account a specific quantity of tokens.| +|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| +|close|This action is the opposite for `open` action, it closes the specified account for specified token.| +|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| +|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| + +The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. + +The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). + +The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. + +Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. + +## eosio.wrap system contract +The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. + +It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. + +However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. + +The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. + +Why is it easier for governance actions to be executed via this contract? +The answer to this question is explained in detailed [here](./guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs_v2/02_compile-and-deploy.md b/docs_v2/02_compile-and-deploy.md new file mode 100644 index 000000000..0d082a8ef --- /dev/null +++ b/docs_v2/02_compile-and-deploy.md @@ -0,0 +1,55 @@ +## How to compile the eosio.contracts + +To compile the eosio.contracts execute the following commands. + +On all platforms except macOS: +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$( nproc ) +cd .. +``` + +For macOS +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$(sysctl -n hw.ncpu) +cd .. +``` + +## To deploy eosio.bios contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testerbios` +``` +cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios +``` + +## To deploy eosio.msig contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testermsig` +``` +cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig +``` + +## To deploy eosio.system contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testersystem` +``` +cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem +``` + +## To deploy eosio.token contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testertoken` +``` +cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken +``` + +## To deploy eosio.wrap contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testerwrap` +``` +cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap +``` \ No newline at end of file diff --git a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md b/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md new file mode 100644 index 000000000..2bd712fb4 --- /dev/null +++ b/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md @@ -0,0 +1,209 @@ +## Upgrading the system contract + +### Indirect method using eosio.msig contract + +Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. + +So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). + +The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. + +The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. + +For now, it is recommended to use the direct method to upgrade the system contract. + +### Direct method (avoids using eosio.msig contract) + +Each of the top 21 block producers should do the following: + +1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): + +``` +$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio +code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 +saving wast to original_system_contract.wast +saving abi to original_system_contract.abi +``` + +2. Generate the unsigned transaction which upgrades the system contract: + +``` +$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json +``` + +The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): + +``` +{ + "expiration": "2018-06-15T22:17:10", + "ref_block_num": 4552, + "ref_block_prefix": 511016679, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], +``` + +and the last few lines should be: + +``` + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: + +3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. + +4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. + +Then each of the top 21 block producers should do the following: + +5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: + +``` +$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json +2,4c2,4 +< "expiration": "2018-06-15T22:17:10", +< "ref_block_num": 4552, +< "ref_block_prefix": 511016679, +--- +> "expiration": "2018-06-15T21:20:39", +> "ref_block_num": 4972, +> "ref_block_prefix": 195390844, +``` + +6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. + +First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. + +Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): + +``` +$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 +private key: "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" + ], + "context_free_data": [] +} +``` + +Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. + +The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. + +When the lead producer collects 15 producer signatures, the lead producer should do the following: + +7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: + +``` +$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 + "transaction_extensions": [], + "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", + "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", + "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", + "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", + "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", + "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", + "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", + "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", + "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", + "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", + "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", + "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", + "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", + "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", + "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" + ], + "context_free_data": [] +} +``` + +8. Push the signed transaction to the blockchain: + +``` +$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json +{ + "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "processed": { + "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "receipt": { + "status": "executed", + "cpu_usage_us": 4909, + "net_usage_words": 15124 + }, + "elapsed": 4909, + "net_usage": 120992, + "scheduled": false, + "action_traces": [{ +... +``` + +If you get an error message like the following: + +``` +Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations +Ensure that you have the related private keys inside your wallet and your wallet is unlocked. +``` + +That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. + +If you get an error message like the following: + +``` +Error 3090002: irrelevant signature included +Please remove the unnecessary signature from your transaction! +``` + +That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. + +If you get an error message like the following: + +``` +Error 3040006: Transaction Expiration Too Far +Please decrease the expiration time of your transaction! +``` + +That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. + +If you get an error message like the following: + +``` +Error 3040005: Expired Transaction +Please increase the expiration time of your transaction! +``` + +That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. + +9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: + +``` +$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio +code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 +saving wast to new_system_contract.wast +saving abi to new_system_contract.abi +$ diff original_system_contract.abi new_system_contract.abi +584,592d583 +< },{ +< "name": "deferred_trx_id", +< "type": "uint32" +< },{ +< "name": "last_unstake_time", +< "type": "time_point_sec" +< },{ +< "name": "unstaking", +< "type": "asset" +``` diff --git a/docs_v2/03_guides/02_how-to-buy-ram.md b/docs_v2/03_guides/02_how-to-buy-ram.md new file mode 100644 index 000000000..19c83a374 --- /dev/null +++ b/docs_v2/03_guides/02_how-to-buy-ram.md @@ -0,0 +1,20 @@ +## How buy RAM + +### What RAM is + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### How to buy RAM + +To check the amount of RAM for an account eostutorial1: +``` +cleos get account eostutorial1 +``` + +Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: +``` +cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active +``` \ No newline at end of file diff --git a/docs_v2/03_guides/03_how-to-stake.md b/docs_v2/03_guides/03_how-to-stake.md new file mode 100644 index 000000000..fb0a5e318 --- /dev/null +++ b/docs_v2/03_guides/03_how-to-stake.md @@ -0,0 +1,47 @@ +## How to stake + +### What staking is + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. + +### Staking tokens for CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active +``` + +### Staking tokens for Bandwidth + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active +``` diff --git a/docs_v2/03_guides/04_how-to-vote.md b/docs_v2/03_guides/04_how-to-vote.md new file mode 100644 index 000000000..7ebb62f76 --- /dev/null +++ b/docs_v2/03_guides/04_how-to-vote.md @@ -0,0 +1,12 @@ +## How to vote + +### What voting is + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +### How to vote + +To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. +``` +cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 +``` \ No newline at end of file diff --git a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md new file mode 100644 index 000000000..3592f0592 --- /dev/null +++ b/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -0,0 +1,146 @@ +## How to create, issue and transfer a token + +## Step 1: Obtain Contract Source + +Navigate to your contracts directory. + +```text +cd CONTRACTS_DIR +``` +Pull the source + +```text +git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +``` +This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. + + +```text +cd eosio.contracts/eosio.token +``` + +## Step 2: Create Account for Contract +Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. +[[info]] +| +You may have to unlock your wallet first! + + +```shell +cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +``` + +## Step 3: Compile the Contract + + +```shell +eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen +``` + +## Step 4: Deploy the Token Contract + + +```shell +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +``` + +Result +```shell +Reading WASM from ... +Publishing contract... +executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us +# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... +# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... +warning: transaction executed locally, but may not be confirmed by the network yet ] +``` + +## Step 5: Create the Token +To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. + +Below is the concise way to call this method, using positional arguments: + +```shell +cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +An alternate approach uses named arguments: + +```shell +cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. + +## Step 6: Issue Tokens +The issuer can issue new tokens to the "alice" account created earlier. + +```text +cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +``` + +Result +```shell +executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles +# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> issue +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> transfer +# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +``` +This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. + +Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. + +To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. + +```shell +cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j +``` + +## Step 7: Transfer Tokens +Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. + +```shell +cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +``` + +Result +```text +executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles +# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +>> transfer +# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +``` +Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) + +```shell +cleos get currency balance eosio.token bob SYS +``` + + +```text +25.00 SYS +``` +Check "alice's" balance, notice that tokens were deducted from the account + +```shell +cleos get currency balance eosio.token alice SYS +``` + + +```text +75.00 SYS +``` +Excellent! Everything adds up. diff --git a/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md new file mode 100644 index 000000000..f68dff871 --- /dev/null +++ b/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -0,0 +1,171 @@ +## eosio.msig examples + +### Cleos usage example for issuing tokens. + +#### Prerequisites: + - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. + - account 'treasury' is the issuer of SYS token. + - account 'tester' exists. + - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. + +#### One user creates a proposal: +```` +$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester + +executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles +# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... +```` + +#### Another user reviews the transaction: +```` +$ cleos multisig review tester test +{ + "proposal_name": "test", + "requested_approvals": [{ + "actor": "treasury", + "permission": "active" + } + ], + "provided_approvals": [], + "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", + "transaction": { + "expiration": "2018-05-01T00:00:00", + "region": 0, + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_kcpu_usage": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "issue", + "authorization": [{ + "actor": "treasury", + "permission": "active" + } + ], + "data": { + "to": "tester", + "quantity": "1000.0000 SYS", + "memo": "" + }, + "hex_data": "000000005c95b1ca809698000000000004454f530000000000" + } + ] + } +} +```` + +#### And then approves it: +```` +$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury + +executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles +# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} +```` + +#### First user initiates execution: +```` +$ cleos multisig exec tester test -p tester + +executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles +# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} +```` + + +### Cleos usage example for transferring tokens. + +#### Prerequisites: + - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. + - account 'treasury' has at least 1.1000 SYS token balance. + - account 'tester' exists. + - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. + +#### One user creates a proposal: +```` +$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester + +executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles +# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... +```` + +#### Another user reviews the transaction: +```` +$ cleos multisig review tester test +{ + "proposal_name": "test", + "requested_approvals": [{ + "actor": "treasury", + "permission": "active" + } + ], + "provided_approvals": [], + "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", + "transaction": { + "expiration": "2018-05-01T00:00:00", + "region": 0, + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_kcpu_usage": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "transfer", + "authorization": [{ + "actor": "treasury", + "permission": "active" + } + ], + "data": { + "from": "treasury", + "to": "tester", + "quantity": "1.0000 SYS", + "memo": "" + }, + "hex_data": "000000005c95b1ca809698000000000004454f530000000000" + } + ] + } +} +```` + +#### And then approves it: +```` +$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury + +executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles +# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} +```` + +#### First user check account balance before executing the proposed transaction +```` +$ cleos get account tester +... +SYS balances: + liquid: 1.0487 SYS + staked: 2.0000 SYS + unstaking: 0.0000 SYS + total: 4.0487 SYS +```` + +#### First user initiates execution of proposed transaction: +```` +$ cleos multisig exec tester test -p tester + +executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles +# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} +```` + +#### First user can check account balance, it should be increased by 1.0000 SYS +```` +$ cleos get account tester +... +SYS balances: + liquid: 2.0487 SYS + staked: 2.0000 SYS + unstaking: 0.0000 SYS + total: 4.0487 SYS +```` diff --git a/docs_v2/03_guides/07_how-to-use-eosio.wrap.md b/docs_v2/03_guides/07_how-to-use-eosio.wrap.md new file mode 100644 index 000000000..0f3395fcb --- /dev/null +++ b/docs_v2/03_guides/07_how-to-use-eosio.wrap.md @@ -0,0 +1,874 @@ +# eosio.wrap + +## 1. Installing the eosio.wrap contract + +The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. + +First, the account `eosio.wrap` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.wrap` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.wrap` account. + +The `eosio.wrap` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. + +This guide will be using cleos to carry out the process. + +### 1.1 Create the eosio.wrap account + +#### 1.1.1 Generate the transaction to create the eosio.wrap account + +The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. + +A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. + +Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. + +First, generate a transaction to capture the necessary actions involved in creating a new account: +``` +$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json +726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} +726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} +$ cat generated_account_creation_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305501000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c660100000001000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c6601000000" + },{ + "account": "eosio", + "name": "buyrambytes", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305500c80000" + },{ + "account": "eosio", + "name": "delegatebw", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` +Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. +The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. + +Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: +``` +$ cat newaccount_payload.json +{ + "creator": "eosio", + "name": "eosio.wrap", + "owner": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": {"actor": "eosio", "permission": "active"}, + "weight": 1 + }], + "waits": [] + }, + "active": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": {"actor": "eosio", "permission": "active"}, + "weight": 1 + }], + "waits": [] + } +} +``` + +Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: +``` +$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json +$ cat generated_newaccount_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: +``` +$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json +$ cat generated_setpriv_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setpriv", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "00004d1a03ea305501" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: +``` +$ cat create_wrap_account_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. + +Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: +``` +$ cat create_wrap_account_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + },{ + "account": "eosio", + "name": "buyrambytes", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305500c80000" + },{ + "account": "eosio", + "name": "delegatebw", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" + },{ + "account": "eosio", + "name": "setpriv", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "00004d1a03ea305501" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The transaction in create_wrap_account_trx.json is now ready to be proposed. + +It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. + +This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. + +In that case, create a file producer_permissions.json with the content shown in the command below: +``` +$ cat producer_permissions.json +[ + {"actor": "blkproducera", "permission": "active"}, + {"actor": "blkproducerb", "permission": "active"}, + {"actor": "blkproducerc", "permission": "active"}, + {"actor": "blkproducerd", "permission": "active"}, + {"actor": "blkproducere", "permission": "active"}, + {"actor": "blkproducerf", "permission": "active"}, + {"actor": "blkproducerg", "permission": "active"}, + {"actor": "blkproducerh", "permission": "active"}, + {"actor": "blkproduceri", "permission": "active"}, + {"actor": "blkproducerj", "permission": "active"}, + {"actor": "blkproducerk", "permission": "active"}, + {"actor": "blkproducerl", "permission": "active"}, + {"actor": "blkproducerm", "permission": "active"}, + {"actor": "blkproducern", "permission": "active"}, + {"actor": "blkproducero", "permission": "active"}, + {"actor": "blkproducerp", "permission": "active"}, + {"actor": "blkproducerq", "permission": "active"}, + {"actor": "blkproducerr", "permission": "active"}, + {"actor": "blkproducers", "permission": "active"}, + {"actor": "blkproducert", "permission": "active"}, + {"actor": "blkproduceru", "permission": "active"} +] +``` + +#### 1.1.2 Propose the transaction to create the eosio.wrap account + +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. + +The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). + +The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. + +The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: +``` +$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera +executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.1.3 Review and approve the transaction to create the eosio.wrap account + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. + +The proposed transaction can be reviewed using the `cleos multisig review` command: +``` +$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json +$ head -n 30 create_wrap_account_trx_to_review.json +{ + "proposal_name": "createwrap", + "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "creator": "eosio", + "name": "eosio.wrap", + "owner": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": { + "actor": "eosio", + "permission": "active" + }, +``` + +The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: +``` +$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex +$ cat expected_create_wrap_trx_serialized.hex +c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 +$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex +$ cat proposed_create_wrap_trx_serialized.hex +c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 +$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.1.4 Execute the transaction to create the eosio.wrap account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera createwrap blkproducera +executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +Anyone can now verify that the `eosio.wrap` was created: +``` +$ cleos get account eosio.wrap +privileged: true +permissions: + owner 1: 1 eosio@active, + active 1: 1 eosio@active, +memory: + quota: 49.74 KiB used: 3.33 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 us + available: 460.8 ms + limit: 460.8 ms + +producers: + +``` + +### 1.2 Deploy the eosio.wrap contract + +#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract + +The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. + +The easy way to generate this transaction is using cleos: +``` +$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json +Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... +Using already assembled WASM... +Publishing contract... +$ cat deploy_wrap_contract_trx.json +{ + "expiration": "2018-06-29T19:55:26", + "ref_block_num": 18544, + "ref_block_prefix": 562790588, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + },{ + "account": "eosio", + "name": "setabi", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: +``` +$ head -n 9 deploy_wrap_contract_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ +``` + +This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. + +#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract + +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. + +The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). + +This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. + +The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: +``` +$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera +executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. + +The proposed transaction can be reviewed using the `cleos multisig review` command: +``` +$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json +$ cat deploy_wrap_contract_trx_to_review.json +{ + "proposal_name": "deploywrap", + "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": { + "account": "eosio.wrap", + "vmtype": 0, + "vmversion": 0, + "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + }, + "hex_data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + },{ + "account": "eosio", + "name": "setabi", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": { + "account": "eosio.wrap", + "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + }, + "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + } + ], + "transaction_extensions": [] + } +} +``` + +Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. + +This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: +``` +$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex +$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 +c0593f5b00000000000000000000020000000000ea30550000 +$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex +$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 +c0593f5b00000000000000000000020000000000ea30550000 +$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.2.4 Execute the transaction to create the eosio.wrap account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera deploywrap blkproducera +executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} +``` + +Anyone can now verify that the `eosio.wrap` contract was deployed correctly. + +``` +$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap +code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c +saving abi to retrieved-eosio.wrap.abi +$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm +1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm +``` + +If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. + +## 2. Using the eosio.wrap contract + +### 2.1 Example: Updating owner authority of an arbitrary account + +This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. + +This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. + +The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: +``` +$ cat producer_permissions.json +[ + {"actor": "blkproducera", "permission": "active"}, + {"actor": "blkproducerb", "permission": "active"}, + {"actor": "blkproducerc", "permission": "active"}, + {"actor": "blkproducerd", "permission": "active"}, + {"actor": "blkproducere", "permission": "active"}, + {"actor": "blkproducerf", "permission": "active"}, + {"actor": "blkproducerg", "permission": "active"}, + {"actor": "blkproducerh", "permission": "active"}, + {"actor": "blkproduceri", "permission": "active"}, + {"actor": "blkproducerj", "permission": "active"}, + {"actor": "blkproducerk", "permission": "active"}, + {"actor": "blkproducerl", "permission": "active"}, + {"actor": "blkproducerm", "permission": "active"}, + {"actor": "blkproducern", "permission": "active"}, + {"actor": "blkproducero", "permission": "active"}, + {"actor": "blkproducerp", "permission": "active"}, + {"actor": "blkproducerq", "permission": "active"}, + {"actor": "blkproducerr", "permission": "active"}, + {"actor": "blkproducers", "permission": "active"}, + {"actor": "blkproducert", "permission": "active"}, + {"actor": "blkproduceru", "permission": "active"} +] +``` + +#### 2.1.1 Generate the transaction to change the owner permission of an account + +The goal of this example is for the block producers to change the owner permission of the account `alice`. + +The initial status of the `alice` account might be: +``` +permissions: + owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV + active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +memory: + quota: 49.74 KiB used: 3.365 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 us + available: 460.8 ms + limit: 460.8 ms + +producers: +``` + +Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. + +The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: +``` +$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json +``` + +Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: +``` +$ cat update_alice_owner_trx.json +{ + "expiration": "1970-01-01T00:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "updateauth", + "authorization": [{ + "actor": "alice", + "permission": "active" + } + ], + "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. + +``` +$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json +``` + +Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. +``` +$ cat wrap_update_alice_owner_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.wrap", + "name": "exec", + "authorization": [{ + "actor": "blkproducera", + "permission": "active" + },{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. + +First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: +``` +$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex +$ cat update_alice_owner_trx_serialized.hex +0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 +``` + +Then generate the template for the transaction containing the `eosio.wrap::exec` action: +``` +$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json +$ cat wrap_update_alice_owner_trx.json +{ + "expiration": "2018-06-29T23:34:01", + "ref_block_num": 23708, + "ref_block_prefix": 3605208482, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.wrap", + "name": "exec", + "authorization": [], + "data": "60ae423ad15b613c" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Then modify the transaction in wrap_update_alice_owner_trx.json as follows: + * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; + * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); + * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. + + +#### 2.1.2 Propose the transaction to change the owner permission of an account + +The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: +``` +$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera +executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.1.3 Review and approve the transaction to change the owner permission of an account + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. +``` +$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json +$ cat wrap_update_alice_owner_trx_to_review.json +{ + "proposal_name": "updatealice", + "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.wrap", + "name": "exec", + "authorization": [{ + "actor": "blkproducera", + "permission": "active" + },{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": { + "executer": "blkproducera", + "trx": { + "expiration": "1970-01-01T00:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "updateauth", + "authorization": [{ + "actor": "alice", + "permission": "active" + } + ], + "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [] + } + }, + "hex_data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" + } + ], + "transaction_extensions": [] + } +} +``` + +The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.wrap::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. + +Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. + +Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: +``` +$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex +$ cat expected_wrap_update_alice_owner_trx_serialized.hex +c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 +$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex +$ cat proposed_wrap_update_alice_owner_trx_serialized.hex +c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 +$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.1.4 Execute the transaction to change the owner permission of an account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera updatealice blkproducera +executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +Anyone can now verify that the owner authority of `alice` was successfully changed: +``` +$ cleos get account alice +permissions: + owner 1: 1 eosio@active, + active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +memory: + quota: 49.74 KiB used: 3.348 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 413 us + available: 460.4 ms + limit: 460.8 ms + +producers: + +``` From 3fe59fb664c8c8fd567d61099386213cf965e3e2 Mon Sep 17 00:00:00 2001 From: ovi Date: Mon, 12 Aug 2019 13:40:34 +0300 Subject: [PATCH 03/97] refactoring after feedback from Sean/Han and incorporating corrections made by Zorba80 we decided to go with the docs_v2 content layout, so renaming docs_v2 to docs. correct the internal links to anchors --- {docs_v2 => docs}/01_introduction.md | 55 +- {docs_v2 => docs}/02_compile-and-deploy.md | 0 .../01_upgrading-the-eosio.system-contract.md | 2 + docs/03_guides/02_how-to-buy-ram.md | 8 + docs/03_guides/03_how-to-stake.md | 8 + docs/03_guides/04_how-to-vote.md | 8 + ...ow-to-create-issue-and-transfer-a-token.md | 44 +- ...-a-multisig-transaction-with-eosio.msig.md | 0 .../03_guides/07_how-to-use-eosio.wrap.md | 0 docs/eosio.bios/deploy.md | 12 - docs/eosio.bios/introduction.md | 30 - docs/eosio.msig/deploy.md | 12 - ...-a-multisig-transaction-with-eosio.msig.md | 171 ---- docs/eosio.msig/introduction.md | 19 - docs/eosio.system/deploy.md | 12 - docs/eosio.system/guides/how-to-buy-ram.md | 20 - docs/eosio.system/guides/how-to-stake.md | 47 - docs/eosio.system/guides/how-to-vote.md | 12 - .../upgrading-the-eosio.system-contract.md | 209 ----- docs/eosio.system/introduction.md | 65 -- docs/eosio.token/deploy.md | 12 - ...ow-to-create-issue-and-transfer-a-token.md | 146 --- docs/eosio.token/introduction.md | 21 - docs/eosio.wrap/deploy.md | 12 - .../guides/how-to-use-eosio.wrap.md | 874 ------------------ docs/eosio.wrap/introduction.md | 12 - docs/introduction.md | 52 -- docs_v2/03_guides/02_how-to-buy-ram.md | 20 - docs_v2/03_guides/03_how-to-stake.md | 47 - docs_v2/03_guides/04_how-to-vote.md | 12 - 30 files changed, 80 insertions(+), 1862 deletions(-) rename {docs_v2 => docs}/01_introduction.md (76%) rename {docs_v2 => docs}/02_compile-and-deploy.md (100%) rename {docs_v2 => docs}/03_guides/01_upgrading-the-eosio.system-contract.md (99%) create mode 100644 docs/03_guides/02_how-to-buy-ram.md create mode 100644 docs/03_guides/03_how-to-stake.md create mode 100644 docs/03_guides/04_how-to-vote.md rename {docs_v2 => docs}/03_guides/05_how-to-create-issue-and-transfer-a-token.md (67%) rename {docs_v2 => docs}/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md (100%) rename {docs_v2 => docs}/03_guides/07_how-to-use-eosio.wrap.md (100%) delete mode 100644 docs/eosio.bios/deploy.md delete mode 100644 docs/eosio.bios/introduction.md delete mode 100644 docs/eosio.msig/deploy.md delete mode 100644 docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md delete mode 100644 docs/eosio.msig/introduction.md delete mode 100644 docs/eosio.system/deploy.md delete mode 100644 docs/eosio.system/guides/how-to-buy-ram.md delete mode 100644 docs/eosio.system/guides/how-to-stake.md delete mode 100644 docs/eosio.system/guides/how-to-vote.md delete mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md delete mode 100644 docs/eosio.system/introduction.md delete mode 100644 docs/eosio.token/deploy.md delete mode 100644 docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md delete mode 100644 docs/eosio.token/introduction.md delete mode 100644 docs/eosio.wrap/deploy.md delete mode 100644 docs/eosio.wrap/guides/how-to-use-eosio.wrap.md delete mode 100644 docs/eosio.wrap/introduction.md delete mode 100644 docs/introduction.md delete mode 100644 docs_v2/03_guides/02_how-to-buy-ram.md delete mode 100644 docs_v2/03_guides/03_how-to-stake.md delete mode 100644 docs_v2/03_guides/04_how-to-vote.md diff --git a/docs_v2/01_introduction.md b/docs/01_introduction.md similarity index 76% rename from docs_v2/01_introduction.md rename to docs/01_introduction.md index b29008924..d1e29f40a 100644 --- a/docs_v2/01_introduction.md +++ b/docs/01_introduction.md @@ -1,10 +1,12 @@ -# About System Contracts +## About System Contracts The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. -Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. +Block.one implements and maintains EOSIO open source platform which contains, as an example, the system contracts encapsulating the base functionality for an EOSIO based blockchain. This document will detail each one of them, [eosio.bios](#eosiobios-system-contract), [eosio.system](#eosiosystem-system-contract), [eosio.msig](#eosiomsig-system-contract), [eosio.token](#eosiotoken-system-contract), [eosio.wrap](#eosiowrap-system-contract) along with a few other main concepts. -## System contracts, system accounts, priviledged accounts +## Concepts + +### System contracts, system accounts, priviledged accounts At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. @@ -26,15 +28,38 @@ As you just learned the relation between an account and a contract, we are addin |eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| |eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| -# System contracts defined in eosio.contracts +### RAM + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM as the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time an account has at its disposal when pushing actions to a contract. + +### NET + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +### Stake + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, in spite of inflation caused by minting new tokens in order to reward BPs for their services every 24 hours. + +### Vote + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these nodes are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +## System contracts defined in eosio.contracts -1. [eosio.bios](#eosio.bios-system-contract) -2. [eosio.system](#eosio.system-system-contract) -3. [eosio.msig](#eosio.msig-system-contract) -4. [eosio.token](#eosio.token-system-contract) -5. [eosio.wrap](#eosio.wrap-system-contract) +1. [eosio.bios](#eosiobios-system-contract) +2. [eosio.system](#eosiosystem-system-contract) +3. [eosio.msig](#eosiomsig-system-contract) +4. [eosio.token](#eosiotoken-system-contract) +5. [eosio.wrap](#eosiowrap-system-contract) -## eosio.bios system contract +### eosio.bios system contract The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. @@ -65,7 +90,7 @@ Below are listed the actions which are declared in the `eosio.bios` contract, ma |onerror|Called every time an error occurs while a transaction was processed.| |setcode|Allows for update of the contract code of an account.| -## eosio.system system contract +### eosio.system system contract The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. @@ -131,7 +156,7 @@ The actions implemented and publicly exposed by the `eosio.system` system contra |onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| |claimrewards|Claim block producing and vote rewards for block producer identified by an account.| -## eosio.msig system contract +### eosio.msig system contract The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. @@ -146,12 +171,12 @@ These are the actions implemented and publicly exposed by the `eosio.msig` contr |---|---| |propose|Creates a proposal containing one transaction.| |approve|Approves an existing proposal.| -|unapprove|Revokes an existing proposal.| +|unapprove|Revokes approval of an existing proposal.| |cancel|Cancels an existing proposal.| |exec|Allows an account to execute a proposal.| |invalidate|Invalidate proposal.| -## eosio.token system contract +### eosio.token system contract The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. @@ -173,7 +198,7 @@ The `eosio.token` contract manages the set of tokens, accounts and their corresp Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. -## eosio.wrap system contract +### eosio.wrap system contract The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. diff --git a/docs_v2/02_compile-and-deploy.md b/docs/02_compile-and-deploy.md similarity index 100% rename from docs_v2/02_compile-and-deploy.md rename to docs/02_compile-and-deploy.md diff --git a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md b/docs/03_guides/01_upgrading-the-eosio.system-contract.md similarity index 99% rename from docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md rename to docs/03_guides/01_upgrading-the-eosio.system-contract.md index 2bd712fb4..953ce0730 100644 --- a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md +++ b/docs/03_guides/01_upgrading-the-eosio.system-contract.md @@ -73,6 +73,8 @@ Then each of the top 21 block producers should do the following: 5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: +TO DO: Shouldn't one of the files be upgrade_system_contract_trx.json? + ``` $ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json 2,4c2,4 diff --git a/docs/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md new file mode 100644 index 000000000..5c4f49d33 --- /dev/null +++ b/docs/03_guides/02_how-to-buy-ram.md @@ -0,0 +1,8 @@ +## How buy RAM + +You can buy RAM using `cleos` command line tool or using a wallet that implements the buy RAM functionality. + +TO DO: add link below +To buy ram using `cleos` check [how to buy ram](how-to-buy-ram). + +To buy ram using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md new file mode 100644 index 000000000..0389415d2 --- /dev/null +++ b/docs/03_guides/03_how-to-stake.md @@ -0,0 +1,8 @@ +## How to stake tokens for CPU and/or NET bandwidth + +You can stake tokens for CPU and/or NET bandwidth using `cleos` command line tool or using a wallet that implements this functionality. + +TO DO: add link below +To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](how-to-stake-resource). + +To stake tokens for CPU and/or NET bandwidth using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md new file mode 100644 index 000000000..babb21955 --- /dev/null +++ b/docs/03_guides/04_how-to-vote.md @@ -0,0 +1,8 @@ +## How to vote + +You can vote using `cleos` command line tool or using a wallet that implements the vote functionality. + +TO DO: add link below +To vote using `cleos` check [how to vote](how-to-vote). + +To vote using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md similarity index 67% rename from docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md rename to docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md index 3592f0592..584e4a648 100644 --- a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -7,24 +7,19 @@ Navigate to your contracts directory. ```text cd CONTRACTS_DIR ``` -Pull the source +Pull the source ```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +git clone https://github.com/EOSIO/eosio.contracts --branch master --single-branch ``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - ```text cd eosio.contracts/eosio.token ``` ## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. [[info]] -| -You may have to unlock your wallet first! - +| You may have to unlock your wallet first! ```shell cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV @@ -32,19 +27,17 @@ cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHu ## Step 3: Compile the Contract - ```shell eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen ``` ## Step 4: Deploy the Token Contract - ```shell cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active ``` -Result +Result should look similar to the one below: ```shell Reading WASM from ... Publishing contract... @@ -55,26 +48,24 @@ warning: transaction executed locally, but may not be confirmed by the network y ``` ## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: ```shell cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active ``` -Result +Result should look similar to the one below: ```shell executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} ``` + An alternate approach uses named arguments: ```shell cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active ``` -Result +Result should look similar to the one below: ```shell executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} @@ -82,13 +73,14 @@ executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. ## Step 6: Issue Tokens + The issuer can issue new tokens to the "alice" account created earlier. ```text cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active ``` -Result +Result should look similar to the one below: ```shell executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles # eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} @@ -98,24 +90,16 @@ executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd411 # eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} # user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` ## Step 7: Transfer Tokens + Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. ```shell cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active ``` -Result +Result should look similar to the one below: ```text executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles # eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} @@ -129,18 +113,18 @@ Now check if "bob" got the tokens using [cleos get currency balance](https://dev cleos get currency balance eosio.token bob SYS ``` - +Result: ```text 25.00 SYS ``` + Check "alice's" balance, notice that tokens were deducted from the account ```shell cleos get currency balance eosio.token alice SYS ``` - +Result: ```text 75.00 SYS ``` -Excellent! Everything adds up. diff --git a/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 100% rename from docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md rename to docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md diff --git a/docs_v2/03_guides/07_how-to-use-eosio.wrap.md b/docs/03_guides/07_how-to-use-eosio.wrap.md similarity index 100% rename from docs_v2/03_guides/07_how-to-use-eosio.wrap.md rename to docs/03_guides/07_how-to-use-eosio.wrap.md diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md deleted file mode 100644 index 57a5923b1..000000000 --- a/docs/eosio.bios/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps deploy eosio.bios contract - -In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerbios` - -``` -cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios -``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md deleted file mode 100644 index fc31c0c77..000000000 --- a/docs/eosio.bios/introduction.md +++ /dev/null @@ -1,30 +0,0 @@ -## Introducing eosio.bios contract - -The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. - -The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. - -|Action name|Action description| -|---|---| -|setpriv|Set privilege status for an account.| -|setalimits|Set the resource limits of an account| -|setglimits|Not implemented yet.| -|setprods|Set a new list of active producers, that is, a new producers' schedule.| -|setparams|Set the blockchain parameters.| -|reqauth|Check if an account has authorization to access the current action.| -|setabi|Set the abi for a contract identified by an account name.| - -The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. - -Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: - -|Action name|Description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md deleted file mode 100644 index d5f027d88..000000000 --- a/docs/eosio.msig/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.msig contract - -In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testermsig` - -``` -cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig -``` \ No newline at end of file diff --git a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md deleted file mode 100644 index f68dff871..000000000 --- a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ /dev/null @@ -1,171 +0,0 @@ -## eosio.msig examples - -### Cleos usage example for issuing tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' is the issuer of SYS token. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "issue", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "to": "tester", - "quantity": "1000.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user initiates execution: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - - -### Cleos usage example for transferring tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' has at least 1.1000 SYS token balance. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "transfer", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "from": "treasury", - "to": "tester", - "quantity": "1.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user check account balance before executing the proposed transaction -```` -$ cleos get account tester -... -SYS balances: - liquid: 1.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` - -#### First user initiates execution of proposed transaction: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - -#### First user can check account balance, it should be increased by 1.0000 SYS -```` -$ cleos get account tester -... -SYS balances: - liquid: 2.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md deleted file mode 100644 index 8fea80569..000000000 --- a/docs/eosio.msig/introduction.md +++ /dev/null @@ -1,19 +0,0 @@ -## Introducing eosio.msig contract - -The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. - -The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: -- first you create a transaction json file, -- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, -- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, -- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. - -These are the actions implemented and publicly exposed by the `eosio.msig` contract: -|Action name|Action description| -|---|---| -|propose|Creates a proposal containing one transaction.| -|approve|Approves an existing proposal.| -|unapprove|Revokes an existing proposal.| -|cancel|Cancels an existing proposal.| -|exec|Allows an account to execute a proposal.| -|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md deleted file mode 100644 index 13703abdf..000000000 --- a/docs/eosio.system/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.system contract - -In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testersystem` - -``` -cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md deleted file mode 100644 index 19c83a374..000000000 --- a/docs/eosio.system/guides/how-to-buy-ram.md +++ /dev/null @@ -1,20 +0,0 @@ -## How buy RAM - -### What RAM is - -RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). -The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). - -### How to buy RAM - -To check the amount of RAM for an account eostutorial1: -``` -cleos get account eostutorial1 -``` - -Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: -``` -cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md deleted file mode 100644 index fb0a5e318..000000000 --- a/docs/eosio.system/guides/how-to-stake.md +++ /dev/null @@ -1,47 +0,0 @@ -## How to stake - -### What staking is - -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. - -### Staking tokens for CPU - -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active -``` - -### Staking tokens for Bandwidth - -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active -``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md deleted file mode 100644 index 7ebb62f76..000000000 --- a/docs/eosio.system/guides/how-to-vote.md +++ /dev/null @@ -1,12 +0,0 @@ -## How to vote - -### What voting is - -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. - -### How to vote - -To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. -``` -cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md deleted file mode 100644 index 2bd712fb4..000000000 --- a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md +++ /dev/null @@ -1,209 +0,0 @@ -## Upgrading the system contract - -### Indirect method using eosio.msig contract - -Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. - -So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). - -The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. - -The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. - -For now, it is recommended to use the direct method to upgrade the system contract. - -### Direct method (avoids using eosio.msig contract) - -Each of the top 21 block producers should do the following: - -1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): - -``` -$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio -code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 -saving wast to original_system_contract.wast -saving abi to original_system_contract.abi -``` - -2. Generate the unsigned transaction which upgrades the system contract: - -``` -$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json -``` - -The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): - -``` -{ - "expiration": "2018-06-15T22:17:10", - "ref_block_num": 4552, - "ref_block_prefix": 511016679, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], -``` - -and the last few lines should be: - -``` - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: - -3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. - -4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. - -Then each of the top 21 block producers should do the following: - -5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: - -``` -$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json -2,4c2,4 -< "expiration": "2018-06-15T22:17:10", -< "ref_block_num": 4552, -< "ref_block_prefix": 511016679, ---- -> "expiration": "2018-06-15T21:20:39", -> "ref_block_num": 4972, -> "ref_block_prefix": 195390844, -``` - -6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. - -First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. - -Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): - -``` -$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 -private key: "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" - ], - "context_free_data": [] -} -``` - -Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. - -The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. - -When the lead producer collects 15 producer signatures, the lead producer should do the following: - -7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: - -``` -$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 - "transaction_extensions": [], - "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", - "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", - "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", - "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", - "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", - "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", - "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", - "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", - "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", - "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", - "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", - "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", - "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", - "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", - "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" - ], - "context_free_data": [] -} -``` - -8. Push the signed transaction to the blockchain: - -``` -$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json -{ - "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "processed": { - "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "receipt": { - "status": "executed", - "cpu_usage_us": 4909, - "net_usage_words": 15124 - }, - "elapsed": 4909, - "net_usage": 120992, - "scheduled": false, - "action_traces": [{ -... -``` - -If you get an error message like the following: - -``` -Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations -Ensure that you have the related private keys inside your wallet and your wallet is unlocked. -``` - -That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. - -If you get an error message like the following: - -``` -Error 3090002: irrelevant signature included -Please remove the unnecessary signature from your transaction! -``` - -That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. - -If you get an error message like the following: - -``` -Error 3040006: Transaction Expiration Too Far -Please decrease the expiration time of your transaction! -``` - -That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. - -If you get an error message like the following: - -``` -Error 3040005: Expired Transaction -Please increase the expiration time of your transaction! -``` - -That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. - -9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: - -``` -$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio -code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 -saving wast to new_system_contract.wast -saving abi to new_system_contract.abi -$ diff original_system_contract.abi new_system_contract.abi -584,592d583 -< },{ -< "name": "deferred_trx_id", -< "type": "uint32" -< },{ -< "name": "last_unstake_time", -< "type": "time_point_sec" -< },{ -< "name": "unstaking", -< "type": "asset" -``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md deleted file mode 100644 index 1ca3ca049..000000000 --- a/docs/eosio.system/introduction.md +++ /dev/null @@ -1,65 +0,0 @@ -## Introducing eosio.system contract - -The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: -- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. -- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. -- Users can buy and sell RAM at a market-determined price. -- Users can bid on premium names. -- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. - -The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - -|Action name|Action description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setabi|Allows for updates of the contract ABI of an account.| -|setcode|Allows for updates of the contract code of an account.| -|init|Initializes the system contract for a version and a symbol.| -|setram|Set the ram supply.| -|setramrate|Set the ram increase rate.| -|setparams|Set the blockchain parameters.| -|setpriv|Set privilege status for an account (turn it on/off).| -|setalimits|Set the resource limits of an account.| -|setacctram|Set the RAM limits of an account.| -|setacctnet|Set the NET limits of an account.| -|setacctcpu|Set the CPU limits of an account.| -|rmvproducer|Deactivates a producer by name, if not found asserts.| -|updtrevision|Updates the current revision.| -|bidname|Allows an account to place a bid for a name.| -|bidrefund|Allows an account to get back the amount it bid so far on a name.| -|deposit|Deposits core tokens to user REX fund.| -|withdraw|Withdraws core tokens from user REX fund.| -|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| -|unstaketorex|Use staked core tokens to buy REX.| -|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| -|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| -|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| -|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| -|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| -|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| -|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| -|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| -|updaterex|Updates REX owner vote weight to current value of held REX tokens.| -|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| -|mvtosavings|Moves a specified amount of REX to savings bucket.| -|mvfrsavings|Moves a specified amount of REX from savings bucket.| -|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| -|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| -|buyrambytes|Increases receiver's ram in quantity of bytes provided.| -|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| -|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| -|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| -|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| -|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| -|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| -|unregprod|Deactivate the block producer with specified account.| -|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| -|regproxy|Set specified account as proxy.| -|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| -|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md deleted file mode 100644 index 5f341b639..000000000 --- a/docs/eosio.token/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.token contract - -In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testertoken` - -``` -cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken -``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md deleted file mode 100644 index 3592f0592..000000000 --- a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md +++ /dev/null @@ -1,146 +0,0 @@ -## How to create, issue and transfer a token - -## Step 1: Obtain Contract Source - -Navigate to your contracts directory. - -```text -cd CONTRACTS_DIR -``` -Pull the source - -```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch -``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - - -```text -cd eosio.contracts/eosio.token -``` - -## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. -[[info]] -| -You may have to unlock your wallet first! - - -```shell -cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -``` - -## Step 3: Compile the Contract - - -```shell -eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen -``` - -## Step 4: Deploy the Token Contract - - -```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active -``` - -Result -```shell -Reading WASM from ... -Publishing contract... -executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us -# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... -# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... -warning: transaction executed locally, but may not be confirmed by the network yet ] -``` - -## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: - -```shell -cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -An alternate approach uses named arguments: - -```shell -cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. - -## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. - -```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active -``` - -Result -```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` - -## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. - -```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active -``` - -Result -```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -``` -Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) - -```shell -cleos get currency balance eosio.token bob SYS -``` - - -```text -25.00 SYS -``` -Check "alice's" balance, notice that tokens were deducted from the account - -```shell -cleos get currency balance eosio.token alice SYS -``` - - -```text -75.00 SYS -``` -Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md deleted file mode 100644 index dcde42fd5..000000000 --- a/docs/eosio.token/introduction.md +++ /dev/null @@ -1,21 +0,0 @@ -## Introducing eosio.token contract - -The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. - -These are the public actions the `eosio.token` contract is implementing: -|Action name|Action description| -|---|---| -|create|Allows an account to create a token in a given supply amount.| -|issue|This action issues to an account a specific quantity of tokens.| -|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| -|close|This action is the opposite for `open` action, it closes the specified account for specified token.| -|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| -|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| - -The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. - -The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). - -The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. - -Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md deleted file mode 100644 index bad4e3bb6..000000000 --- a/docs/eosio.wrap/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.wrap contract - -In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerwrap` - -``` -cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap -``` \ No newline at end of file diff --git a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md deleted file mode 100644 index 0f3395fcb..000000000 --- a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md +++ /dev/null @@ -1,874 +0,0 @@ -# eosio.wrap - -## 1. Installing the eosio.wrap contract - -The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. - -First, the account `eosio.wrap` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.wrap` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.wrap` account. - -The `eosio.wrap` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. - -This guide will be using cleos to carry out the process. - -### 1.1 Create the eosio.wrap account - -#### 1.1.1 Generate the transaction to create the eosio.wrap account - -The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. - -Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. - -First, generate a transaction to capture the necessary actions involved in creating a new account: -``` -$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json -726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} -726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} -$ cat generated_account_creation_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305501000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c660100000001000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c6601000000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` -Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. -The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. - -Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: -``` -$ cat newaccount_payload.json -{ - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - }, - "active": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - } -} -``` - -Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: -``` -$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json -$ cat generated_newaccount_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: -``` -$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json -$ cat generated_setpriv_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. - -Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - },{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The transaction in create_wrap_account_trx.json is now ready to be proposed. - -It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. - -In that case, create a file producer_permissions.json with the content shown in the command below: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 1.1.2 Propose the transaction to create the eosio.wrap account - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: -``` -$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera -executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.3 Review and approve the transaction to create the eosio.wrap account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json -$ head -n 30 create_wrap_account_trx_to_review.json -{ - "proposal_name": "createwrap", - "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": { - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": { - "actor": "eosio", - "permission": "active" - }, -``` - -The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: -``` -$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex -$ cat expected_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex -$ cat proposed_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera createwrap blkproducera -executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the `eosio.wrap` was created: -``` -$ cleos get account eosio.wrap -privileged: true -permissions: - owner 1: 1 eosio@active, - active 1: 1 eosio@active, -memory: - quota: 49.74 KiB used: 3.33 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: - -``` - -### 1.2 Deploy the eosio.wrap contract - -#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract - -The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -The easy way to generate this transaction is using cleos: -``` -$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json -Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... -Using already assembled WASM... -Publishing contract... -$ cat deploy_wrap_contract_trx.json -{ - "expiration": "2018-06-29T19:55:26", - "ref_block_num": 18544, - "ref_block_prefix": 562790588, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: -``` -$ head -n 9 deploy_wrap_contract_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ -``` - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. - -#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: -``` -$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera -executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json -$ cat deploy_wrap_contract_trx_to_review.json -{ - "proposal_name": "deploywrap", - "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "vmtype": 0, - "vmversion": 0, - "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - }, - "hex_data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - }, - "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [] - } -} -``` - -Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. - -This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: -``` -$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex -$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex -$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera deploywrap blkproducera -executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} -``` - -Anyone can now verify that the `eosio.wrap` contract was deployed correctly. - -``` -$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap -code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c -saving abi to retrieved-eosio.wrap.abi -$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm -1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm -``` - -If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. - -## 2. Using the eosio.wrap contract - -### 2.1 Example: Updating owner authority of an arbitrary account - -This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. - -This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. - -The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 2.1.1 Generate the transaction to change the owner permission of an account - -The goal of this example is for the block producers to change the owner permission of the account `alice`. - -The initial status of the `alice` account might be: -``` -permissions: - owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.365 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: -``` - -Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. - -The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: -``` -$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json -``` - -Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: -``` -$ cat update_alice_owner_trx.json -{ - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. - -``` -$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json -``` - -Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. -``` -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. - -First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: -``` -$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex -$ cat update_alice_owner_trx_serialized.hex -0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 -``` - -Then generate the template for the transaction containing the `eosio.wrap::exec` action: -``` -$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-06-29T23:34:01", - "ref_block_num": 23708, - "ref_block_prefix": 3605208482, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [], - "data": "60ae423ad15b613c" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Then modify the transaction in wrap_update_alice_owner_trx.json as follows: - * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; - * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); - * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. - - -#### 2.1.2 Propose the transaction to change the owner permission of an account - -The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: -``` -$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera -executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.3 Review and approve the transaction to change the owner permission of an account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. -``` -$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json -$ cat wrap_update_alice_owner_trx_to_review.json -{ - "proposal_name": "updatealice", - "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "executer": "blkproducera", - "trx": { - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [] - } - }, - "hex_data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [] - } -} -``` - -The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.wrap::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. - -Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. - -Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: -``` -$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex -$ cat expected_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex -$ cat proposed_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.4 Execute the transaction to change the owner permission of an account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera updatealice blkproducera -executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the owner authority of `alice` was successfully changed: -``` -$ cleos get account alice -permissions: - owner 1: 1 eosio@active, - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.348 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 413 us - available: 460.4 ms - limit: 460.8 ms - -producers: - -``` diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md deleted file mode 100644 index db4adc63e..000000000 --- a/docs/eosio.wrap/introduction.md +++ /dev/null @@ -1,12 +0,0 @@ -## Introducing eosio.wrap contract - -The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. - -It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. - -However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. - -The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. - -Why is it easier for governance actions to be executed via this contract? -The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md deleted file mode 100644 index 226ce05e3..000000000 --- a/docs/introduction.md +++ /dev/null @@ -1,52 +0,0 @@ -## About System Contracts - -The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. - -Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. - -## System contracts, system accounts, priviledged accounts - -At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. - -As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: -|Account|Priviledged|Has contract|Description| -|---|---|---|---| -|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| -|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| -|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| -|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| -|eosio.names|No|No|The account which is holding funds from namespace auctions.| -|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| -|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| -|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| -|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| -|eosio.saving|No|No|The account which holds the 4% of network inflation.| -|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| -|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| -|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| - -## How to compile the eosio.contracts - -To compile the eosio.contracts execute the following commands. - -On all platforms except macOS: -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$( nproc ) -cd .. -``` - -For macOS -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$(sysctl -n hw.ncpu) -cd .. -``` \ No newline at end of file diff --git a/docs_v2/03_guides/02_how-to-buy-ram.md b/docs_v2/03_guides/02_how-to-buy-ram.md deleted file mode 100644 index 19c83a374..000000000 --- a/docs_v2/03_guides/02_how-to-buy-ram.md +++ /dev/null @@ -1,20 +0,0 @@ -## How buy RAM - -### What RAM is - -RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). -The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). - -### How to buy RAM - -To check the amount of RAM for an account eostutorial1: -``` -cleos get account eostutorial1 -``` - -Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: -``` -cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active -``` \ No newline at end of file diff --git a/docs_v2/03_guides/03_how-to-stake.md b/docs_v2/03_guides/03_how-to-stake.md deleted file mode 100644 index fb0a5e318..000000000 --- a/docs_v2/03_guides/03_how-to-stake.md +++ /dev/null @@ -1,47 +0,0 @@ -## How to stake - -### What staking is - -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. - -### Staking tokens for CPU - -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active -``` - -### Staking tokens for Bandwidth - -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active -``` diff --git a/docs_v2/03_guides/04_how-to-vote.md b/docs_v2/03_guides/04_how-to-vote.md deleted file mode 100644 index 7ebb62f76..000000000 --- a/docs_v2/03_guides/04_how-to-vote.md +++ /dev/null @@ -1,12 +0,0 @@ -## How to vote - -### What voting is - -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. - -### How to vote - -To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. -``` -cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 -``` \ No newline at end of file From ff925d9de3a0d9a7af53f027f5f284a11aedd652 Mon Sep 17 00:00:00 2001 From: Sandwich Date: Mon, 12 Aug 2019 13:51:18 +0200 Subject: [PATCH 04/97] Adjust annotations, remove typedef docs and adjust files --- .../include/eosio.bios/eosio.bios.hpp | 19 - .../include/eosio.msig/eosio.msig.hpp | 7 +- .../include/eosio.system/eosio.system.hpp | 311 ++----- .../include/eosio.system/exchange_state.hpp | 3 +- .../include/eosio.token/eosio.token.hpp | 45 +- docs.json | 30 +- {docs_v2 => docs}/01_introduction.md | 0 {docs_v2 => docs}/02_compile-and-deploy.md | 0 .../01_upgrading-the-eosio.system-contract.md | 0 .../03_guides/02_how-to-buy-ram.md | 0 .../03_guides/03_how-to-stake.md | 0 {docs_v2 => docs}/03_guides/04_how-to-vote.md | 0 ...ow-to-create-issue-and-transfer-a-token.md | 0 ...-a-multisig-transaction-with-eosio.msig.md | 0 .../03_guides/07_how-to-use-eosio.wrap.md | 0 docs/eosio.bios/deploy.md | 12 - docs/eosio.bios/introduction.md | 30 - docs/eosio.msig/deploy.md | 12 - ...-a-multisig-transaction-with-eosio.msig.md | 171 ---- docs/eosio.msig/introduction.md | 19 - docs/eosio.system/deploy.md | 12 - docs/eosio.system/guides/how-to-buy-ram.md | 20 - docs/eosio.system/guides/how-to-stake.md | 47 - docs/eosio.system/guides/how-to-vote.md | 12 - .../upgrading-the-eosio.system-contract.md | 209 ----- docs/eosio.system/introduction.md | 65 -- docs/eosio.token/deploy.md | 12 - ...w-to-create,-issue-and-transfer-a-token.md | 152 --- ...ow-to-create-issue-and-transfer-a-token.md | 146 --- docs/eosio.token/introduction.md | 21 - docs/eosio.wrap/deploy.md | 12 - .../guides/how-to-use-eosio.wrap.md | 874 ------------------ docs/eosio.wrap/introduction.md | 12 - docs/introduction.md | 52 -- 34 files changed, 100 insertions(+), 2205 deletions(-) rename {docs_v2 => docs}/01_introduction.md (100%) rename {docs_v2 => docs}/02_compile-and-deploy.md (100%) rename {docs_v2 => docs}/03_guides/01_upgrading-the-eosio.system-contract.md (100%) rename {docs_v2 => docs}/03_guides/02_how-to-buy-ram.md (100%) rename {docs_v2 => docs}/03_guides/03_how-to-stake.md (100%) rename {docs_v2 => docs}/03_guides/04_how-to-vote.md (100%) rename {docs_v2 => docs}/03_guides/05_how-to-create-issue-and-transfer-a-token.md (100%) rename {docs_v2 => docs}/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md (100%) rename {docs_v2 => docs}/03_guides/07_how-to-use-eosio.wrap.md (100%) delete mode 100644 docs/eosio.bios/deploy.md delete mode 100644 docs/eosio.bios/introduction.md delete mode 100644 docs/eosio.msig/deploy.md delete mode 100644 docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md delete mode 100644 docs/eosio.msig/introduction.md delete mode 100644 docs/eosio.system/deploy.md delete mode 100644 docs/eosio.system/guides/how-to-buy-ram.md delete mode 100644 docs/eosio.system/guides/how-to-stake.md delete mode 100644 docs/eosio.system/guides/how-to-vote.md delete mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md delete mode 100644 docs/eosio.system/introduction.md delete mode 100644 docs/eosio.token/deploy.md delete mode 100644 docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md delete mode 100644 docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md delete mode 100644 docs/eosio.token/introduction.md delete mode 100644 docs/eosio.wrap/deploy.md delete mode 100644 docs/eosio.wrap/guides/how-to-use-eosio.wrap.md delete mode 100644 docs/eosio.wrap/introduction.md delete mode 100644 docs/introduction.md diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 3fa4a4cdb..4807abc0b 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -38,25 +38,6 @@ namespace eosio { } } -/** - * EOSIO Contracts - * - * @details The design of the EOSIO blockchain calls for a number of smart contracts that are run at a - * privileged permission level in order to support functions such as block producer registration and - * voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart - * contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. - * - * This repository contains examples of these privileged contracts that are useful when deploying, - * managing, and/or using an EOSIO blockchain. They are provided for reference purposes: - * - eosio.bios - * - eosio.system - * - eosio.msig - * - eosio.wrap - * - * The following unprivileged contract(s) are also part of the system. - * - eosio.token - */ - namespace eosio { using eosio::ignore; diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index cd9237349..465433ec0 100644 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -6,6 +6,7 @@ #include namespace eosio { + /** * @defgroup eosiomsig eosio.msig * @ingroup eosiocontracts @@ -27,8 +28,7 @@ namespace eosio { * authorized by the provided keys and permissions, and if the proposal name doesn’t * already exist; if all validations pass the `proposal_name` and `trx` trasanction are * saved in the proposals table and the `requested` permission levels to the - * approvals table (for the `proposer` context). - * Storage changes are billed to `proposer`. + * approvals table (for the `proposer` context). Storage changes are billed to `proposer`. * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be unique for proposer) @@ -46,8 +46,7 @@ namespace eosio { * proposed by `proposer`. If the proposal's requested approval list contains the `level` * permission then the `level` permission is moved from internal `requested_approvals` list to * internal `provided_approvals` list of the proposal, thus persisting the approval for - * the `proposal_name` proposal. - * Storage changes are billed to `proposer`. + * the `proposal_name` proposal. Storage changes are billed to `proposer`. * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be unique for proposer) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index f2ebe9a32..b98db3525 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -89,9 +89,7 @@ namespace eosiosystem { */ /** - * A name bid. - * - * @details A name bid consists of: + * A name bid, which consists of: * - a `newname` name that the bid is for * - a `high_bidder` account name that is the one with the highest bid so far * - the `high_bid` which is amount of highest bid @@ -108,9 +106,7 @@ namespace eosiosystem { }; /** - * A bid refund. - * - * @details A bid refund is defined by: + * A bid refund, which is defined by: * - the `bidder` account name owning the refund * - the `amount` to be refunded */ @@ -120,21 +116,10 @@ namespace eosiosystem { uint64_t primary_key()const { return bidder.value; } }; - - /** - * Name bid table - * - * @details The name bid table is storing all the `name_bid`s instances. - */ typedef eosio::multi_index< "namebids"_n, name_bid, indexed_by<"highbid"_n, const_mem_fun > > name_bid_table; - /** - * Bid refund table. - * - * @details The bid refund table is storing all the `bid_refund`s instances. - */ typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; /** @@ -243,9 +228,7 @@ namespace eosiosystem { }; /** - * Voter info. - * - * @details Voter info stores information about the voter: + * Voter info. Voter info stores information about the voter: * - `owner` the voter * - `proxy` the proxy set by the voter, if any * - `producers` the producers approved by this voter if no proxy set @@ -288,40 +271,23 @@ namespace eosiosystem { EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(flags1)(reserved2)(reserved3) ) }; - /** - * Voters table - * - * @details The voters table stores all the `voter_info`s instances, all voters information. - */ + typedef eosio::multi_index< "voters"_n, voter_info > voters_table; - /** - * Defines producer info table added in version 1.0 - */ typedef eosio::multi_index< "producers"_n, producer_info, indexed_by<"prototalvote"_n, const_mem_fun > > producers_table; - /** - * Defines new producer info table added in version 1.3.0 - */ + typedef eosio::multi_index< "producers2"_n, producer_info2 > producers_table2; - /** - * Global state singleton added in version 1.0 - */ + typedef eosio::singleton< "global"_n, eosio_global_state > global_state_singleton; - /** - * Global state singleton added in version 1.1.0 - */ + typedef eosio::singleton< "global2"_n, eosio_global_state2 > global_state2_singleton; - /** - * Global state singleton added in version 1.3 - */ + typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; - /** - * Global state singleton added in version 1.6.x - */ + typedef eosio::singleton< "global4"_n, eosio_global_state4 > global_state4_singleton; struct [[eosio::table, eosio::contract("eosio.system")]] user_resources { @@ -367,18 +333,13 @@ namespace eosiosystem { EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(net_amount)(cpu_amount) ) }; - /** - * These tables are designed to be constructed in the scope of the relevant user, this - * facilitates simpler API for per-user queries - */ + typedef eosio::multi_index< "userres"_n, user_resources > user_resources_table; typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; /** - * `rex_pool` structure underlying the rex pool table. - * - * @details A rex pool table entry is defined by: + * `rex_pool` structure underlying the rex pool table. A rex pool table entry is defined by: * - `version` defaulted to zero, * - `total_lent` total amount of CORE_SYMBOL in open rex_loans * - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), @@ -401,18 +362,10 @@ namespace eosiosystem { uint64_t primary_key()const { return 0; } }; - /** - * Rex pool table - * - * @details The rex pool table is storing the only one instance of rex_pool which it stores - * the global state of the REX system. - */ typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; /** - * `rex_fund` structure underlying the rex fund table. - * - * @details A rex fund table entry is defined by: + * `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: * - `version` defaulted to zero, * - `owner` the owner of the rex fund, * - `balance` the balance of the fund. @@ -425,17 +378,10 @@ namespace eosiosystem { uint64_t primary_key()const { return owner.value; } }; - /** - * Rex fund table - * - * @details The rex fund table is storing all the `rex_fund`s instances. - */ typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; /** - * `rex_balance` structure underlying the rex balance table. - * - * @details A rex balance table entry is defined by: + * `rex_balance` structure underlying the rex balance table. A rex balance table entry is defined by: * - `version` defaulted to zero, * - `owner` the owner of the rex fund, * - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, @@ -453,17 +399,10 @@ namespace eosiosystem { uint64_t primary_key()const { return owner.value; } }; - /** - * Rex balance table - * - * @details The rex balance table is storing all the `rex_balance`s instances. - */ typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; /** - * `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. - * - * @details A rex net/cpu loan table entry is defined by: + * `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. A rex net/cpu loan table entry is defined by: * - `version` defaulted to zero, * - `from` account creating and paying for loan, * - `receiver` account receiving rented resources, @@ -489,21 +428,11 @@ namespace eosiosystem { uint64_t by_owner()const { return from.value; } }; - /** - * Rex cpu loan table - * - * @details The rex cpu loan table is storing all the `rex_loan`s instances for cpu, indexed by loan number, expiration and owner. - */ typedef eosio::multi_index< "cpuloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, indexed_by<"byowner"_n, const_mem_fun> > rex_cpu_loan_table; - /** - * Rex net loan table - * - * @details The rex net loan table is storing all the `rex_loan`s instances for net, indexed by loan number, expiration and owner. - */ typedef eosio::multi_index< "netloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, indexed_by<"byowner"_n, const_mem_fun> @@ -523,11 +452,6 @@ namespace eosiosystem { uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } }; - /** - * Rex order table - * - * @details The rex order table is storing all the `rex_order`s instances, indexed by owner and time and owner. - */ typedef eosio::multi_index< "rexqueue"_n, rex_order, indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; @@ -538,9 +462,7 @@ namespace eosiosystem { }; /** - * The EOSIO system contract. - * - * @details The EOSIO system contract governs ram market, voters, producers, global state. + * The EOSIO system contract. The EOSIO system contract governs ram market, voters, producers, global state. */ class [[eosio::contract("eosio.system")]] system_contract : public native { @@ -578,15 +500,6 @@ namespace eosiosystem { static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); - /** - * System contract constructor. - * - * @details Constructs a system contract based on self account, code account and data. - * - * @param s - The current code account that is executing the action, - * @param code - The original code account that executed the action, - * @param ds - The contract data represented as an `eosio::datastream`. - */ system_contract( name s, name code, datastream ds ); ~system_contract(); @@ -603,9 +516,7 @@ namespace eosiosystem { // Actions: /** - * Init action. - * - * @details Init action initializes the system contract for a version and a symbol. + * The Init action initializes the system contract for a version and a symbol. * Only succeeds when: * - version is 0 and * - symbol is found and @@ -619,9 +530,7 @@ namespace eosiosystem { void init( unsigned_int version, const symbol& core ); /** - * On block action. - * - * @details This special action is triggered when a block is applied by the given producer + * On block action. This special action is triggered when a block is applied by the given producer * and cannot be generated from any other source. It is used to pay producers and calculate * missed blocks of other producers. Producer pay is deposited into the producer's stake * balance and can be withdrawn over time. If blocknum is the start of a new round this may @@ -633,9 +542,7 @@ namespace eosiosystem { void onblock( ignore header ); /** - * Set account limits action. - * - * @details Set the resource limits of an account + * Set account limits action sets the resource limits of an account * * @param account - name of the account whose resource limit to be set, * @param ram_bytes - ram limit in absolute bytes, @@ -646,9 +553,7 @@ namespace eosiosystem { void setalimits( const name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); /** - * Set account RAM limits action. - * - * @details Set the RAM limits of an account + * Set account RAM limits action, which sets the RAM limits of an account * * @param account - name of the account whose resource limit to be set, * @param ram_bytes - ram limit in absolute bytes. @@ -657,9 +562,7 @@ namespace eosiosystem { void setacctram( const name& account, const std::optional& ram_bytes ); /** - * Set account NET limits action. - * - * @details Set the NET limits of an account + * Set account NET limits action, which sets the NET limits of an account * * @param account - name of the account whose resource limit to be set, * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts). @@ -668,9 +571,7 @@ namespace eosiosystem { void setacctnet( const name& account, const std::optional& net_weight ); /** - * Set account CPU limits action. - * - * @details Set the CPU limits of an account + * Set account CPU limits action, which sets the CPU limits of an account * * @param account - name of the account whose resource limit to be set, * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). @@ -680,9 +581,7 @@ namespace eosiosystem { /** - * Activates a protocol feature. - * - * @details Activates a protocol feature + * Activates a protocol feature * * @param feature_digest - hash of the protocol feature to activate. */ @@ -692,9 +591,7 @@ namespace eosiosystem { // functions defined in delegate_bandwidth.cpp /** - * Delegate bandwidth and/or cpu action. - * - * @details Stakes SYS from the balance of `from` for the benefit of `receiver`. + * Delegate bandwidth and/or cpu action. Stakes SYS from the balance of `from` for the benefit of `receiver`. * * @param from - the account to delegate bandwidth from, that is, the account holding * tokens to be staked, @@ -720,9 +617,7 @@ namespace eosiosystem { void setrex( const asset& balance ); /** - * Deposit to REX fund action. - * - * @details Deposits core tokens to user REX fund. + * Deposit to REX fund action. Deposits core tokens to user REX fund. * All proceeds and expenses related to REX are added to or taken out of this fund. * An inline transfer from 'owner' liquid balance is executed. * All REX-related costs and proceeds are deducted from and added to 'owner' REX fund, @@ -748,9 +643,7 @@ namespace eosiosystem { void withdraw( const name& owner, const asset& amount ); /** - * Buyrex action. - * - * @details Buys REX in exchange for tokens taken out of user's REX fund by transfering + * Buyrex action. Buys REX in exchange for tokens taken out of user's REX fund by transfering * core tokens from user REX fund and converts them to REX stake. By buying REX, user is * lending tokens in order to be rented as CPU or NET resourses. * Storage change is billed to 'from' account. @@ -769,9 +662,7 @@ namespace eosiosystem { void buyrex( const name& from, const asset& amount ); /** - * Unstaketorex action. - * - * @details Use staked core tokens to buy REX. + * Unstaketorex action. Use staked core tokens to buy REX. * Storage change is billed to 'owner' account. * * @param owner - owner of staked tokens, @@ -790,9 +681,7 @@ namespace eosiosystem { void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); /** - * Sellrex action. - * - * @details Sells REX in exchange for core tokens by converting REX stake back into core tokens + * Sellrex action. Sells REX in exchange for core tokens by converting REX stake back into core tokens * at current exchange rate. If order cannot be processed, it gets queued until there is enough * in REX pool to fill order, and will be processed within 30 days at most. If successful, user * votes are updated, that is, proceeds are deducted from user's voting power. In case sell order @@ -805,9 +694,7 @@ namespace eosiosystem { void sellrex( const name& from, const asset& rex ); /** - * Cnclrexorder action. - * - * @details Cancels unfilled REX sell order by owner if one exists. + * Cnclrexorder action. Cancels unfilled REX sell order by owner if one exists. * * @param owner - owner account name. * @@ -817,9 +704,7 @@ namespace eosiosystem { void cnclrexorder( const name& owner ); /** - * Rentcpu action. - * - * @details Use payment to rent as many SYS tokens as possible as determined by market price and + * Rentcpu action. Use payment to rent as many SYS tokens as possible as determined by market price and * stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user @@ -839,9 +724,7 @@ namespace eosiosystem { void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Rentnet action. - * - * @details Use payment to rent as many SYS tokens as possible as determined by market price and + * Rentnet action. Use payment to rent as many SYS tokens as possible as determined by market price and * stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user @@ -861,9 +744,7 @@ namespace eosiosystem { void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Fundcpuloan action. - * - * @details Transfers tokens from REX fund to the fund of a specific CPU loan in order to + * Fundcpuloan action. Transfers tokens from REX fund to the fund of a specific CPU loan in order to * be used for loan renewal at expiry. * * @param from - loan creator account, @@ -874,9 +755,7 @@ namespace eosiosystem { void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); /** - * Fundnetloan action. - * - * @details Transfers tokens from REX fund to the fund of a specific NET loan in order to + * Fundnetloan action. Transfers tokens from REX fund to the fund of a specific NET loan in order to * be used for loan renewal at expiry. * * @param from - loan creator account, @@ -887,9 +766,7 @@ namespace eosiosystem { void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); /** - * Defcpuloan action. - * - * @details Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. + * Defcpuloan action. Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. * * @param from - loan creator account, * @param loan_num - loan id, @@ -899,9 +776,7 @@ namespace eosiosystem { void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); /** - * Defnetloan action. - * - * @details Withdraws tokens from the fund of a specific NET loan and adds them to REX fund. + * Defnetloan action. Withdraws tokens from the fund of a specific NET loan and adds them to REX fund. * * @param from - loan creator account, * @param loan_num - loan id, @@ -911,9 +786,7 @@ namespace eosiosystem { void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); /** - * Updaterex action. - * - * @details Updates REX owner vote weight to current value of held REX tokens. + * Updaterex action. Updates REX owner vote weight to current value of held REX tokens. * * @param owner - REX owner account. */ @@ -921,9 +794,7 @@ namespace eosiosystem { void updaterex( const name& owner ); /** - * Rexexec action. - * - * @details Processes max CPU loans, max NET loans, and max queued sellrex orders. + * Rexexec action. Processes max CPU loans, max NET loans, and max queued sellrex orders. * Action does not execute anything related to a specific user. * * @param user - any account can execute this action, @@ -933,9 +804,7 @@ namespace eosiosystem { void rexexec( const name& user, uint16_t max ); /** - * Consolidate action. - * - * @details Consolidates REX maturity buckets into one bucket that can be sold after 4 days + * Consolidate action. Consolidates REX maturity buckets into one bucket that can be sold after 4 days * starting from the end of the day. * * @param owner - REX owner account name. @@ -944,9 +813,7 @@ namespace eosiosystem { void consolidate( const name& owner ); /** - * Mvtosavings action. - * - * @details Moves a specified amount of REX into savings bucket. REX savings bucket + * Mvtosavings action. Moves a specified amount of REX into savings bucket. REX savings bucket * never matures. In order for it to be sold, it has to be moved explicitly * out of that bucket. Then the moved amount will have the regular maturity * period of 4 days starting from the end of the day. @@ -958,9 +825,7 @@ namespace eosiosystem { void mvtosavings( const name& owner, const asset& rex ); /** - * Mvfrsavings action. - * - * @details Moves a specified amount of REX out of savings bucket. The moved amount + * Mvfrsavings action. Moves a specified amount of REX out of savings bucket. The moved amount * will have the regular REX maturity period of 4 days. * * @param owner - REX owner account name. @@ -970,9 +835,7 @@ namespace eosiosystem { void mvfrsavings( const name& owner, const asset& rex ); /** - * Closerex action. - * - * @details Deletes owner records from REX tables and frees used RAM. Owner must not have + * Closerex action. Deletes owner records from REX tables and frees used RAM. Owner must not have * an outstanding REX balance. * * @param owner - user account name. @@ -986,9 +849,7 @@ namespace eosiosystem { void closerex( const name& owner ); /** - * Undelegate bandwitdh action. - * - * @details Decreases the total tokens delegated by `from` to `receiver` and/or + * Undelegate bandwitdh action. Decreases the total tokens delegated by `from` to `receiver` and/or * frees the memory associated with the delegation if there is nothing * left to delegate. * This will cause an immediate reduction in net/cpu bandwidth of the @@ -1019,9 +880,7 @@ namespace eosiosystem { const asset& unstake_net_quantity, const asset& unstake_cpu_quantity ); /** - * Buy ram action. - * - * @details Increases receiver's ram quota based upon current price and quantity of + * Buy ram action. Increases receiver's ram quota based upon current price and quantity of * tokens provided. An inline transfer from receiver to system contract of * tokens will be executed. * @@ -1033,9 +892,7 @@ namespace eosiosystem { void buyram( const name& payer, const name& receiver, const asset& quant ); /** - * Buy a specific amount of ram bytes action. - * - * @details Increases receiver's ram in quantity of bytes provided. + * Buy a specific amount of ram bytes action. Increases receiver's ram in quantity of bytes provided. * An inline transfer from receiver to system contract of tokens will be executed. * * @param payer - the ram buyer, @@ -1046,9 +903,7 @@ namespace eosiosystem { void buyrambytes( const name& payer, const name& receiver, uint32_t bytes ); /** - * Sell ram action. - * - * @details Reduces quota by bytes and then performs an inline transfer of tokens + * Sell ram action. Reduces quota by bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. * * @param account - the ram seller account, @@ -1058,9 +913,7 @@ namespace eosiosystem { void sellram( const name& account, int64_t bytes ); /** - * Refund action. - * - * @details This action is called after the delegation-period to claim all pending + * Refund action. This action is called after the delegation-period to claim all pending * unstaked tokens belonging to owner. * * @param owner - the owner of the tokens claimed. @@ -1071,9 +924,7 @@ namespace eosiosystem { // functions defined in voting.cpp /** - * Register producer action. - * - * @details Register producer action, indicates that a particular account wishes to become a producer, + * Register producer action. Register producer action, indicates that a particular account wishes to become a producer, * this action will create a `producer_config` and a `producer_info` object for `producer` scope * in producers tables. * @@ -1090,27 +941,21 @@ namespace eosiosystem { void regproducer( const name& producer, const public_key& producer_key, const std::string& url, uint16_t location ); /** - * Unregister producer action. - * - * @details Deactivate the block producer with account name `producer`. + * Unregister producer action. Deactivate the block producer with account name `producer`. * @param producer - the block producer account to unregister. */ [[eosio::action]] void unregprod( const name& producer ); /** - * Set ram action. - * - * @details Set the ram supply. + * Set ram action sets the ram supply * @param max_ram_size - the amount of ram supply to set. */ [[eosio::action]] void setram( uint64_t max_ram_size ); /** - * Set ram rate action. - - * @details Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to + * Set ram rate action. Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to * a maximum rate of 3 TB per year. If update_ram_supply hasn't been called for the most recent block, * then new ram will be allocated at the old rate up to the present block before switching the rate. * @@ -1120,9 +965,7 @@ namespace eosiosystem { void setramrate( uint16_t bytes_per_block ); /** - * Vote producer action. - * - * @details Votes for a set of producers. This action updates the list of `producers` voted for, + * Vote producer action. Votes for a set of producers. This action updates the list of `producers` voted for, * for `voter` account. If voting for a `proxy`, the producer votes will not change until the * proxy updates their own vote. Voter can vote for a proxy __or__ a list of at most 30 producers. * Storage change is billed to `voter`. @@ -1148,9 +991,7 @@ namespace eosiosystem { void voteproducer( const name& voter, const name& proxy, const std::vector& producers ); /** - * Register proxy action. - * - * @details Set `proxy` account as proxy. + * Register proxy action. Set `proxy` account as proxy. * An account marked as a proxy can vote with the weight of other accounts which * have selected it as a proxy. Other accounts must refresh their voteproducer to * update the proxy's weight. @@ -1166,29 +1007,22 @@ namespace eosiosystem { void regproxy( const name& proxy, bool isproxy ); /** - * Set the blockchain parameters - * - * @details Set the blockchain parameters. By tunning these parameters a degree of + * Set the blockchain parameters Set the blockchain parameters. By tunning these parameters a degree of * customization can be achieved. * @param params - New blockchain parameters to set. */ [[eosio::action]] void setparams( const eosio::blockchain_parameters& params ); - // functions defined in producer_pay.cpp /** - * Claim rewards action. - * - * @details Claim block producing and vote rewards. + * Claim rewards action. Claim block producing and vote rewards. * @param owner - producer account claiming per-block and per-vote rewards. */ [[eosio::action]] void claimrewards( const name& owner ); /** - * Set privilege status for an account. - * - * @details Allows to set privilege status for an account (turn it on/off). + * Set privilege status for an account. Allows to set privilege status for an account (turn it on/off). * @param account - the account to set the privileged status for. * @param is_priv - 0 for false, > 0 for true. */ @@ -1196,18 +1030,14 @@ namespace eosiosystem { void setpriv( const name& account, uint8_t is_priv ); /** - * Remove producer action. - * - * @details Deactivates a producer by name, if not found asserts. + * Remove producer action. Deactivates a producer by name, if not found asserts. * @param producer - the producer account to deactivate. */ [[eosio::action]] void rmvproducer( const name& producer ); /** - * Update revision action. - * - * @details Updates the current revision. + * Update revision action. Updates the current revision. * @param revision - it has to be incremented by 1 compared with current revision. * * @pre Current revision can not be higher than 254, and has to be smaller @@ -1217,9 +1047,7 @@ namespace eosiosystem { void updtrevision( uint8_t revision ); /** - * Bid name action. - * - * @details Allows an account `bidder` to place a bid for a name `newname`. + * Bid name action. Allows an account `bidder` to place a bid for a name `newname`. * @param bidder - the account placing the bid, * @param newname - the name the bid is placed for, * @param bid - the amount of system tokens payed for the bid. @@ -1238,9 +1066,7 @@ namespace eosiosystem { void bidname( const name& bidder, const name& newname, const asset& bid ); /** - * Bid refund action. - * - * @details Allows the account `bidder` to get back the amount it bid so far on a `newname` name. + * Bid refund action. Allows the account `bidder` to get back the amount it bid so far on a `newname` name. * * @param bidder - the account that gets refunded, * @param newname - the name for which the bid was placed and now it gets refunded for. @@ -1249,23 +1075,9 @@ namespace eosiosystem { void bidrefund( const name& bidder, const name& newname ); /** - * Set inflation action. - * - * @details Change the annual inflation rate of the core token supply and specify how + * Change the annual inflation rate of the core token supply and specify how * the new issued tokens will be distributed based on the following structure. - * - * +----+ +----------------+ - * +rate| +--------->|per vote reward | - * +--+-+ | +----------------+ - * | +-----+------+ - * | +----->| bp rewards | - * v | +-----+------+ - * +-+--+---+-+ | +----------------+ - * |new tokens| +--------->|per block reward| - * +----+-----+ +----------------+ - * | +------------+ - * +----->| savings | - * +------------+ + * * @param annual_rate - Annual inflation rate of the core token supply. * (eg. For 5% Annual inflation => annual_rate=500 @@ -1427,5 +1239,4 @@ namespace eosiosystem { registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; }; - /** @}*/ // end of @defgroup eosiosystem eosio.system -} /// eosiosystem +} diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 999ea7d71..64a238227 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -59,5 +59,4 @@ namespace eosiosystem { }; typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; - /** @}*/ // enf of @addtogroup eosiosystem -} /// namespace eosiosystem +} diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index bb08ca409..08d146092 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -14,23 +14,16 @@ namespace eosio { using std::string; /** - * @defgroup eosiotoken eosio.token - * @ingroup eosiocontracts - * - * eosio.token contract - * - * @details eosio.token contract defines the structures and actions that allow users to create, issue, and manage + * eosio.token contract defines the structures and actions that allow users to create, issue, and manage * tokens on eosio based blockchains. - * @{ */ class [[eosio::contract("eosio.token")]] token : public contract { public: using contract::contract; /** - * Create action. + * Allows `issuer` account to create a token in supply of `maximum_supply`. If validation is successful a new entry in statstable for token symbol scope gets created. * - * @details Allows `issuer` account to create a token in supply of `maximum_supply`. * @param issuer - the account that creates the token, * @param maximum_supply - the maximum supply set for the token created. * @@ -38,16 +31,12 @@ namespace eosio { * @pre Token symbol must not be already created, * @pre maximum_supply has to be smaller than the maximum supply allowed by the system: 1^62 - 1. * @pre Maximum supply must be positive; - * - * If validation is successful a new entry in statstable for token symbol scope gets created. */ [[eosio::action]] void create( const name& issuer, const asset& maximum_supply); /** - * Issue action. - * - * @details This action issues to `to` account a `quantity` of tokens. + * This action issues to `to` account a `quantity` of tokens. * * @param to - the account to issue tokens to, it must be the same as the issuer, * @param quntity - the amount of tokens to be issued, @@ -57,9 +46,7 @@ namespace eosio { void issue( const name& to, const asset& quantity, const string& memo ); /** - * Retire action. - * - * @details The opposite for create action, if all validations succeed, + * The opposite for create action, if all validations succeed, * it debits the statstable.supply amount. * * @param quantity - the quantity of tokens to retire, @@ -69,9 +56,7 @@ namespace eosio { void retire( const asset& quantity, const string& memo ); /** - * Transfer action. - * - * @details Allows `from` account to transfer to `to` account the `quantity` tokens. + * Allows `from` account to transfer to `to` account the `quantity` tokens. * One account is debited and the other is credited with quantity tokens. * * @param from - the account to transfer from, @@ -85,9 +70,7 @@ namespace eosio { const asset& quantity, const string& memo ); /** - * Open action. - * - * @details Allows `ram_payer` to create an account `owner` with zero balance for + * Allows `ram_payer` to create an account `owner` with zero balance for * token `symbol` at the expense of `ram_payer`. * * @param owner - the account to be created, @@ -101,9 +84,7 @@ namespace eosio { void open( const name& owner, const symbol& symbol, const name& ram_payer ); /** - * Close action. - * - * @details This action is the opposite for open, it closes the account `owner` + * This action is the opposite for open, it closes the account `owner` * for token `symbol`. * * @param owner - the owner account to execute the close action for, @@ -116,9 +97,7 @@ namespace eosio { void close( const name& owner, const symbol& symbol ); /** - * Get supply method. - * - * @details Gets the supply for token `sym_code`, created by `token_contract_account` account. + * Gets the supply for token `sym_code`, created by `token_contract_account` account. * * @param token_contract_account - the account to get the supply for, * @param sym_code - the symbol to get the supply for. @@ -131,9 +110,7 @@ namespace eosio { } /** - * Get balance method. - * - * @details Get the balance for a token `sym_code` created by `token_contract_account` account, + * Get the balance for a token `sym_code` created by `token_contract_account` account, * for account `owner`. * * @param token_contract_account - the token creator account, @@ -174,5 +151,5 @@ namespace eosio { void sub_balance( const name& owner, const asset& value ); void add_balance( const name& owner, const asset& value, const name& ram_payer ); }; - /** @}*/ // end of @defgroup eosiotoken eosio.token -} /// namespace eosio + +} diff --git a/docs.json b/docs.json index f6a7a50c1..2d4e43af7 100644 --- a/docs.json +++ b/docs.json @@ -8,15 +8,33 @@ } }, { - "name": "doxygen_to_xml", + "name": "mdjavadoc", "options": { - "output": "00_eosio.token", - "INPUT": "eosio.token" + "source_dirs": [ + "contracts/eosio.token/include/eosio.token/", + "contracts/eosio.wrap/include/eosio.wrap/", + "contracts/eosio.bios/include/eosio.bios/", + "contracts/eosio.system/include/eosio.system/", + "contracts/eosio.msig/include/eosio.msig/" + ], + "output_dir": "action-reference" + } + } + ], + "skip_default_filters": true, + "filters": [ + { + "name": "sanitize", + "options": { + "exclude": ["action-reference"] } }, { - "name": "doxybook", - "options": {} + "name": "capitalize", + "options": { + "mode": "all", + "exclude": ["action-reference"] + } } ] -} \ No newline at end of file +} diff --git a/docs_v2/01_introduction.md b/docs/01_introduction.md similarity index 100% rename from docs_v2/01_introduction.md rename to docs/01_introduction.md diff --git a/docs_v2/02_compile-and-deploy.md b/docs/02_compile-and-deploy.md similarity index 100% rename from docs_v2/02_compile-and-deploy.md rename to docs/02_compile-and-deploy.md diff --git a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md b/docs/03_guides/01_upgrading-the-eosio.system-contract.md similarity index 100% rename from docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md rename to docs/03_guides/01_upgrading-the-eosio.system-contract.md diff --git a/docs_v2/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md similarity index 100% rename from docs_v2/03_guides/02_how-to-buy-ram.md rename to docs/03_guides/02_how-to-buy-ram.md diff --git a/docs_v2/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md similarity index 100% rename from docs_v2/03_guides/03_how-to-stake.md rename to docs/03_guides/03_how-to-stake.md diff --git a/docs_v2/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md similarity index 100% rename from docs_v2/03_guides/04_how-to-vote.md rename to docs/03_guides/04_how-to-vote.md diff --git a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md similarity index 100% rename from docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md rename to docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md diff --git a/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 100% rename from docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md rename to docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md diff --git a/docs_v2/03_guides/07_how-to-use-eosio.wrap.md b/docs/03_guides/07_how-to-use-eosio.wrap.md similarity index 100% rename from docs_v2/03_guides/07_how-to-use-eosio.wrap.md rename to docs/03_guides/07_how-to-use-eosio.wrap.md diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md deleted file mode 100644 index 57a5923b1..000000000 --- a/docs/eosio.bios/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps deploy eosio.bios contract - -In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerbios` - -``` -cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios -``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md deleted file mode 100644 index fc31c0c77..000000000 --- a/docs/eosio.bios/introduction.md +++ /dev/null @@ -1,30 +0,0 @@ -## Introducing eosio.bios contract - -The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. - -The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. - -|Action name|Action description| -|---|---| -|setpriv|Set privilege status for an account.| -|setalimits|Set the resource limits of an account| -|setglimits|Not implemented yet.| -|setprods|Set a new list of active producers, that is, a new producers' schedule.| -|setparams|Set the blockchain parameters.| -|reqauth|Check if an account has authorization to access the current action.| -|setabi|Set the abi for a contract identified by an account name.| - -The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. - -Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: - -|Action name|Description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md deleted file mode 100644 index d5f027d88..000000000 --- a/docs/eosio.msig/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.msig contract - -In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testermsig` - -``` -cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig -``` \ No newline at end of file diff --git a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md deleted file mode 100644 index f68dff871..000000000 --- a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ /dev/null @@ -1,171 +0,0 @@ -## eosio.msig examples - -### Cleos usage example for issuing tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' is the issuer of SYS token. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "issue", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "to": "tester", - "quantity": "1000.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user initiates execution: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - - -### Cleos usage example for transferring tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' has at least 1.1000 SYS token balance. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "transfer", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "from": "treasury", - "to": "tester", - "quantity": "1.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user check account balance before executing the proposed transaction -```` -$ cleos get account tester -... -SYS balances: - liquid: 1.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` - -#### First user initiates execution of proposed transaction: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - -#### First user can check account balance, it should be increased by 1.0000 SYS -```` -$ cleos get account tester -... -SYS balances: - liquid: 2.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md deleted file mode 100644 index 8fea80569..000000000 --- a/docs/eosio.msig/introduction.md +++ /dev/null @@ -1,19 +0,0 @@ -## Introducing eosio.msig contract - -The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. - -The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: -- first you create a transaction json file, -- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, -- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, -- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. - -These are the actions implemented and publicly exposed by the `eosio.msig` contract: -|Action name|Action description| -|---|---| -|propose|Creates a proposal containing one transaction.| -|approve|Approves an existing proposal.| -|unapprove|Revokes an existing proposal.| -|cancel|Cancels an existing proposal.| -|exec|Allows an account to execute a proposal.| -|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md deleted file mode 100644 index 13703abdf..000000000 --- a/docs/eosio.system/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.system contract - -In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testersystem` - -``` -cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md deleted file mode 100644 index 19c83a374..000000000 --- a/docs/eosio.system/guides/how-to-buy-ram.md +++ /dev/null @@ -1,20 +0,0 @@ -## How buy RAM - -### What RAM is - -RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). -The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). - -### How to buy RAM - -To check the amount of RAM for an account eostutorial1: -``` -cleos get account eostutorial1 -``` - -Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: -``` -cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md deleted file mode 100644 index fb0a5e318..000000000 --- a/docs/eosio.system/guides/how-to-stake.md +++ /dev/null @@ -1,47 +0,0 @@ -## How to stake - -### What staking is - -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. - -### Staking tokens for CPU - -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active -``` - -### Staking tokens for Bandwidth - -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active -``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md deleted file mode 100644 index 7ebb62f76..000000000 --- a/docs/eosio.system/guides/how-to-vote.md +++ /dev/null @@ -1,12 +0,0 @@ -## How to vote - -### What voting is - -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. - -### How to vote - -To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. -``` -cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md deleted file mode 100644 index 2bd712fb4..000000000 --- a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md +++ /dev/null @@ -1,209 +0,0 @@ -## Upgrading the system contract - -### Indirect method using eosio.msig contract - -Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. - -So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). - -The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. - -The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. - -For now, it is recommended to use the direct method to upgrade the system contract. - -### Direct method (avoids using eosio.msig contract) - -Each of the top 21 block producers should do the following: - -1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): - -``` -$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio -code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 -saving wast to original_system_contract.wast -saving abi to original_system_contract.abi -``` - -2. Generate the unsigned transaction which upgrades the system contract: - -``` -$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json -``` - -The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): - -``` -{ - "expiration": "2018-06-15T22:17:10", - "ref_block_num": 4552, - "ref_block_prefix": 511016679, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], -``` - -and the last few lines should be: - -``` - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: - -3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. - -4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. - -Then each of the top 21 block producers should do the following: - -5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: - -``` -$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json -2,4c2,4 -< "expiration": "2018-06-15T22:17:10", -< "ref_block_num": 4552, -< "ref_block_prefix": 511016679, ---- -> "expiration": "2018-06-15T21:20:39", -> "ref_block_num": 4972, -> "ref_block_prefix": 195390844, -``` - -6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. - -First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. - -Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): - -``` -$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 -private key: "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" - ], - "context_free_data": [] -} -``` - -Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. - -The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. - -When the lead producer collects 15 producer signatures, the lead producer should do the following: - -7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: - -``` -$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 - "transaction_extensions": [], - "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", - "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", - "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", - "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", - "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", - "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", - "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", - "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", - "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", - "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", - "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", - "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", - "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", - "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", - "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" - ], - "context_free_data": [] -} -``` - -8. Push the signed transaction to the blockchain: - -``` -$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json -{ - "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "processed": { - "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "receipt": { - "status": "executed", - "cpu_usage_us": 4909, - "net_usage_words": 15124 - }, - "elapsed": 4909, - "net_usage": 120992, - "scheduled": false, - "action_traces": [{ -... -``` - -If you get an error message like the following: - -``` -Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations -Ensure that you have the related private keys inside your wallet and your wallet is unlocked. -``` - -That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. - -If you get an error message like the following: - -``` -Error 3090002: irrelevant signature included -Please remove the unnecessary signature from your transaction! -``` - -That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. - -If you get an error message like the following: - -``` -Error 3040006: Transaction Expiration Too Far -Please decrease the expiration time of your transaction! -``` - -That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. - -If you get an error message like the following: - -``` -Error 3040005: Expired Transaction -Please increase the expiration time of your transaction! -``` - -That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. - -9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: - -``` -$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio -code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 -saving wast to new_system_contract.wast -saving abi to new_system_contract.abi -$ diff original_system_contract.abi new_system_contract.abi -584,592d583 -< },{ -< "name": "deferred_trx_id", -< "type": "uint32" -< },{ -< "name": "last_unstake_time", -< "type": "time_point_sec" -< },{ -< "name": "unstaking", -< "type": "asset" -``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md deleted file mode 100644 index 1ca3ca049..000000000 --- a/docs/eosio.system/introduction.md +++ /dev/null @@ -1,65 +0,0 @@ -## Introducing eosio.system contract - -The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: -- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. -- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. -- Users can buy and sell RAM at a market-determined price. -- Users can bid on premium names. -- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. - -The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - -|Action name|Action description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setabi|Allows for updates of the contract ABI of an account.| -|setcode|Allows for updates of the contract code of an account.| -|init|Initializes the system contract for a version and a symbol.| -|setram|Set the ram supply.| -|setramrate|Set the ram increase rate.| -|setparams|Set the blockchain parameters.| -|setpriv|Set privilege status for an account (turn it on/off).| -|setalimits|Set the resource limits of an account.| -|setacctram|Set the RAM limits of an account.| -|setacctnet|Set the NET limits of an account.| -|setacctcpu|Set the CPU limits of an account.| -|rmvproducer|Deactivates a producer by name, if not found asserts.| -|updtrevision|Updates the current revision.| -|bidname|Allows an account to place a bid for a name.| -|bidrefund|Allows an account to get back the amount it bid so far on a name.| -|deposit|Deposits core tokens to user REX fund.| -|withdraw|Withdraws core tokens from user REX fund.| -|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| -|unstaketorex|Use staked core tokens to buy REX.| -|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| -|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| -|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| -|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| -|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| -|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| -|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| -|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| -|updaterex|Updates REX owner vote weight to current value of held REX tokens.| -|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| -|mvtosavings|Moves a specified amount of REX to savings bucket.| -|mvfrsavings|Moves a specified amount of REX from savings bucket.| -|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| -|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| -|buyrambytes|Increases receiver's ram in quantity of bytes provided.| -|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| -|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| -|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| -|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| -|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| -|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| -|unregprod|Deactivate the block producer with specified account.| -|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| -|regproxy|Set specified account as proxy.| -|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| -|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md deleted file mode 100644 index 5f341b639..000000000 --- a/docs/eosio.token/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.token contract - -In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testertoken` - -``` -cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken -``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md deleted file mode 100644 index 59dc04512..000000000 --- a/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md +++ /dev/null @@ -1,152 +0,0 @@ -TO DO: use this: -https://dash.readme.io/project/eosio-home/v2.3.8/docs/token-contract -(don't use below link cause it is deprecated) -https://dash.readme.io/project/eosio-cpp/v1.6/docs/quick-start-token - -## How to create, issue and transfer a token - - -## Step 1: Obtain Contract Source - -Navigate to your contracts directory. - -```text -cd CONTRACTS_DIR -``` -Pull the source - -```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch -``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - - -```text -cd eosio.contracts/eosio.token -``` - -## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. -[[info]] -| -You may have to unlock your wallet first! - - -```shell -cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -``` - -## Step 3: Compile the Contract - - -```shell -eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen -``` - -## Step 4: Deploy the Token Contract - - -```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active -``` - -Result -```shell -Reading WASM from ... -Publishing contract... -executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us -# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... -# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... -warning: transaction executed locally, but may not be confirmed by the network yet ] -``` - -## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: - -```shell -cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -An alternate approach uses named arguments: - -```shell -cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. - -## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. - -```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active -``` - -Result -```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` - -## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. - -```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active -``` - -Result -```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -``` -Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) - -```shell -cleos get currency balance eosio.token bob SYS -``` - - -```text -25.00 SYS -``` -Check "alice's" balance, notice that tokens were deducted from the account - -```shell -cleos get currency balance eosio.token alice SYS -``` - - -```text -75.00 SYS -``` -Excellent! Everything adds up. diff --git a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md deleted file mode 100644 index 3592f0592..000000000 --- a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md +++ /dev/null @@ -1,146 +0,0 @@ -## How to create, issue and transfer a token - -## Step 1: Obtain Contract Source - -Navigate to your contracts directory. - -```text -cd CONTRACTS_DIR -``` -Pull the source - -```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch -``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - - -```text -cd eosio.contracts/eosio.token -``` - -## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. -[[info]] -| -You may have to unlock your wallet first! - - -```shell -cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -``` - -## Step 3: Compile the Contract - - -```shell -eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen -``` - -## Step 4: Deploy the Token Contract - - -```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active -``` - -Result -```shell -Reading WASM from ... -Publishing contract... -executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us -# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... -# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... -warning: transaction executed locally, but may not be confirmed by the network yet ] -``` - -## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: - -```shell -cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -An alternate approach uses named arguments: - -```shell -cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. - -## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. - -```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active -``` - -Result -```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` - -## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. - -```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active -``` - -Result -```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -``` -Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) - -```shell -cleos get currency balance eosio.token bob SYS -``` - - -```text -25.00 SYS -``` -Check "alice's" balance, notice that tokens were deducted from the account - -```shell -cleos get currency balance eosio.token alice SYS -``` - - -```text -75.00 SYS -``` -Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md deleted file mode 100644 index dcde42fd5..000000000 --- a/docs/eosio.token/introduction.md +++ /dev/null @@ -1,21 +0,0 @@ -## Introducing eosio.token contract - -The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. - -These are the public actions the `eosio.token` contract is implementing: -|Action name|Action description| -|---|---| -|create|Allows an account to create a token in a given supply amount.| -|issue|This action issues to an account a specific quantity of tokens.| -|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| -|close|This action is the opposite for `open` action, it closes the specified account for specified token.| -|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| -|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| - -The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. - -The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). - -The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. - -Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md deleted file mode 100644 index bad4e3bb6..000000000 --- a/docs/eosio.wrap/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.wrap contract - -In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerwrap` - -``` -cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap -``` \ No newline at end of file diff --git a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md deleted file mode 100644 index 0f3395fcb..000000000 --- a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md +++ /dev/null @@ -1,874 +0,0 @@ -# eosio.wrap - -## 1. Installing the eosio.wrap contract - -The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. - -First, the account `eosio.wrap` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.wrap` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.wrap` account. - -The `eosio.wrap` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. - -This guide will be using cleos to carry out the process. - -### 1.1 Create the eosio.wrap account - -#### 1.1.1 Generate the transaction to create the eosio.wrap account - -The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. - -Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. - -First, generate a transaction to capture the necessary actions involved in creating a new account: -``` -$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json -726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} -726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} -$ cat generated_account_creation_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305501000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c660100000001000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c6601000000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` -Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. -The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. - -Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: -``` -$ cat newaccount_payload.json -{ - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - }, - "active": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - } -} -``` - -Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: -``` -$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json -$ cat generated_newaccount_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: -``` -$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json -$ cat generated_setpriv_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. - -Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - },{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The transaction in create_wrap_account_trx.json is now ready to be proposed. - -It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. - -In that case, create a file producer_permissions.json with the content shown in the command below: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 1.1.2 Propose the transaction to create the eosio.wrap account - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: -``` -$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera -executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.3 Review and approve the transaction to create the eosio.wrap account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json -$ head -n 30 create_wrap_account_trx_to_review.json -{ - "proposal_name": "createwrap", - "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": { - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": { - "actor": "eosio", - "permission": "active" - }, -``` - -The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: -``` -$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex -$ cat expected_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex -$ cat proposed_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera createwrap blkproducera -executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the `eosio.wrap` was created: -``` -$ cleos get account eosio.wrap -privileged: true -permissions: - owner 1: 1 eosio@active, - active 1: 1 eosio@active, -memory: - quota: 49.74 KiB used: 3.33 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: - -``` - -### 1.2 Deploy the eosio.wrap contract - -#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract - -The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -The easy way to generate this transaction is using cleos: -``` -$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json -Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... -Using already assembled WASM... -Publishing contract... -$ cat deploy_wrap_contract_trx.json -{ - "expiration": "2018-06-29T19:55:26", - "ref_block_num": 18544, - "ref_block_prefix": 562790588, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: -``` -$ head -n 9 deploy_wrap_contract_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ -``` - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. - -#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: -``` -$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera -executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json -$ cat deploy_wrap_contract_trx_to_review.json -{ - "proposal_name": "deploywrap", - "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "vmtype": 0, - "vmversion": 0, - "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - }, - "hex_data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - }, - "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [] - } -} -``` - -Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. - -This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: -``` -$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex -$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex -$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera deploywrap blkproducera -executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} -``` - -Anyone can now verify that the `eosio.wrap` contract was deployed correctly. - -``` -$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap -code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c -saving abi to retrieved-eosio.wrap.abi -$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm -1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm -``` - -If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. - -## 2. Using the eosio.wrap contract - -### 2.1 Example: Updating owner authority of an arbitrary account - -This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. - -This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. - -The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 2.1.1 Generate the transaction to change the owner permission of an account - -The goal of this example is for the block producers to change the owner permission of the account `alice`. - -The initial status of the `alice` account might be: -``` -permissions: - owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.365 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: -``` - -Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. - -The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: -``` -$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json -``` - -Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: -``` -$ cat update_alice_owner_trx.json -{ - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. - -``` -$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json -``` - -Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. -``` -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. - -First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: -``` -$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex -$ cat update_alice_owner_trx_serialized.hex -0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 -``` - -Then generate the template for the transaction containing the `eosio.wrap::exec` action: -``` -$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-06-29T23:34:01", - "ref_block_num": 23708, - "ref_block_prefix": 3605208482, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [], - "data": "60ae423ad15b613c" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Then modify the transaction in wrap_update_alice_owner_trx.json as follows: - * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; - * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); - * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. - - -#### 2.1.2 Propose the transaction to change the owner permission of an account - -The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: -``` -$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera -executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.3 Review and approve the transaction to change the owner permission of an account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. -``` -$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json -$ cat wrap_update_alice_owner_trx_to_review.json -{ - "proposal_name": "updatealice", - "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "executer": "blkproducera", - "trx": { - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [] - } - }, - "hex_data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [] - } -} -``` - -The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.wrap::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. - -Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. - -Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: -``` -$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex -$ cat expected_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex -$ cat proposed_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.4 Execute the transaction to change the owner permission of an account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera updatealice blkproducera -executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the owner authority of `alice` was successfully changed: -``` -$ cleos get account alice -permissions: - owner 1: 1 eosio@active, - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.348 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 413 us - available: 460.4 ms - limit: 460.8 ms - -producers: - -``` diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md deleted file mode 100644 index db4adc63e..000000000 --- a/docs/eosio.wrap/introduction.md +++ /dev/null @@ -1,12 +0,0 @@ -## Introducing eosio.wrap contract - -The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. - -It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. - -However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. - -The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. - -Why is it easier for governance actions to be executed via this contract? -The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md deleted file mode 100644 index 226ce05e3..000000000 --- a/docs/introduction.md +++ /dev/null @@ -1,52 +0,0 @@ -## About System Contracts - -The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. - -Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. - -## System contracts, system accounts, priviledged accounts - -At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. - -As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: -|Account|Priviledged|Has contract|Description| -|---|---|---|---| -|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| -|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| -|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| -|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| -|eosio.names|No|No|The account which is holding funds from namespace auctions.| -|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| -|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| -|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| -|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| -|eosio.saving|No|No|The account which holds the 4% of network inflation.| -|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| -|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| -|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| - -## How to compile the eosio.contracts - -To compile the eosio.contracts execute the following commands. - -On all platforms except macOS: -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$( nproc ) -cd .. -``` - -For macOS -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$(sysctl -n hw.ncpu) -cd .. -``` \ No newline at end of file From ff91a49924e8a459a19cec3d398734a71c9748f1 Mon Sep 17 00:00:00 2001 From: Sandwich Date: Mon, 12 Aug 2019 14:57:54 +0200 Subject: [PATCH 05/97] remove second docs.json --- docs2.json | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 docs2.json diff --git a/docs2.json b/docs2.json deleted file mode 100644 index c009574b5..000000000 --- a/docs2.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "eosio.contracts", - "generators": [ - { - "name": "collate_markdown", - "options": { - "docs_dir": "docs" - } - }, - { - "name": "doxygen_to_xml", - "options": { - "INPUT": "eosio.bios eosio.system eosio.msig eosio.token eosio.wrap" - } - }, - { - "name": "doxybook", - "options": {} - } - ] -} \ No newline at end of file From f15511e5b8792c57fd055dce95a1163175da928e Mon Sep 17 00:00:00 2001 From: ovi Date: Mon, 12 Aug 2019 16:26:24 +0300 Subject: [PATCH 06/97] annotating rex.results.cpp as well rewording the NET explanation to be more concise --- .../include/eosio.system/rex.results.hpp | 31 +++++++++++++++++++ docs/01_introduction.md | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index b5a1949c9..791bed529 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -13,17 +13,48 @@ class [[eosio::contract("rex.results")]] rex_results : eosio::contract { using eosio::contract::contract; + /** + * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. + * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. + * An inline convenience action does not have any effect, however, + * its data includes the result of the parent action and appears in its trace. + * @{ + */ + + /** + * Buyresult action. + * + * @param rex_received - amount of tokens used in buy order + */ [[eosio::action]] void buyresult( const asset& rex_received ); + /** + * Sellresult action. + * + * @param proceeds - amount of tokens used in sell order + */ [[eosio::action]] void sellresult( const asset& proceeds ); + /** + * Orderresult action. + * + * @param owner - the owner of the order + * @param proceeds - amount of tokens used in order + */ [[eosio::action]] void orderresult( const name& owner, const asset& proceeds ); + /** + * Rentresult action. + * + * @param rented_tokens - amount of rented tokens + */ [[eosio::action]] void rentresult( const asset& rented_tokens ); + + /** @}*/ using buyresult_action = action_wrapper<"buyresult"_n, &rex_results::buyresult>; using sellresult_action = action_wrapper<"sellresult"_n, &rex_results::sellresult>; diff --git a/docs/01_introduction.md b/docs/01_introduction.md index d1e29f40a..fc52b2f21 100644 --- a/docs/01_introduction.md +++ b/docs/01_introduction.md @@ -41,7 +41,7 @@ CPU is processing power, the amount of CPU an account has is measured in microse ### NET -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is reffered to as "net bandwidth" on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. ### Stake From 5662155aaa15b8911e7d8c854371485a8334f3ca Mon Sep 17 00:00:00 2001 From: ovi Date: Tue, 13 Aug 2019 11:14:25 +0300 Subject: [PATCH 07/97] fix a typo and position correctly annotation for rex.results class --- .../include/eosio.system/rex.results.hpp | 16 ++++++---------- docs/01_introduction.md | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index 791bed529..29af85339 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -8,19 +8,17 @@ using eosio::action_wrapper; using eosio::asset; using eosio::name; +/** + * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. + * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. + * An inline convenience action does not have any effect, however, + * its data includes the result of the parent action and appears in its trace. + */ class [[eosio::contract("rex.results")]] rex_results : eosio::contract { public: using eosio::contract::contract; - /** - * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. - * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. - * An inline convenience action does not have any effect, however, - * its data includes the result of the parent action and appears in its trace. - * @{ - */ - /** * Buyresult action. * @@ -53,8 +51,6 @@ class [[eosio::contract("rex.results")]] rex_results : eosio::contract { */ [[eosio::action]] void rentresult( const asset& rented_tokens ); - - /** @}*/ using buyresult_action = action_wrapper<"buyresult"_n, &rex_results::buyresult>; using sellresult_action = action_wrapper<"sellresult"_n, &rex_results::sellresult>; diff --git a/docs/01_introduction.md b/docs/01_introduction.md index fc52b2f21..50b0052e9 100644 --- a/docs/01_introduction.md +++ b/docs/01_introduction.md @@ -41,7 +41,7 @@ CPU is processing power, the amount of CPU an account has is measured in microse ### NET -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is reffered to as "net bandwidth" on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is referred to as "net bandwidth" on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. ### Stake From 9c7383807705764112abb28c00c177ec0b8ec5eb Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 14 Aug 2019 11:19:36 +0300 Subject: [PATCH 08/97] correct relative links to md files --- docs/01_introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/01_introduction.md b/docs/01_introduction.md index 50b0052e9..9ef079987 100644 --- a/docs/01_introduction.md +++ b/docs/01_introduction.md @@ -160,7 +160,7 @@ The actions implemented and publicly exposed by the `eosio.system` system contra The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. -The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: - first you create a transaction json file, - then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, - the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, @@ -208,4 +208,4 @@ However, the current method is opaque and leaves undesirable side effects on spe The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. Why is it easier for governance actions to be executed via this contract? -The answer to this question is explained in detailed [here](./guides/how-to-use-eosio.wrap.md) \ No newline at end of file +The answer to this question is explained in detailed [here](./03_guides/07_how-to-use-eosio.wrap.md) \ No newline at end of file From e151db6372b2f1b8b691f9ad61ee6a14ebe4caee Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 14 Aug 2019 11:24:10 +0300 Subject: [PATCH 09/97] correct links to eos how-to's --- docs/03_guides/02_how-to-buy-ram.md | 4 ++-- docs/03_guides/03_how-to-stake.md | 4 ++-- docs/03_guides/04_how-to-vote.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md index 5c4f49d33..878757e35 100644 --- a/docs/03_guides/02_how-to-buy-ram.md +++ b/docs/03_guides/02_how-to-buy-ram.md @@ -2,7 +2,7 @@ You can buy RAM using `cleos` command line tool or using a wallet that implements the buy RAM functionality. -TO DO: add link below -To buy ram using `cleos` check [how to buy ram](how-to-buy-ram). +TO DO: verify and correct the next url +To buy ram using `cleos` check [how to buy ram](https://eosio.github.io/eos/cleos/how-to-buy-ram) To buy ram using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md index 0389415d2..bf2a1f381 100644 --- a/docs/03_guides/03_how-to-stake.md +++ b/docs/03_guides/03_how-to-stake.md @@ -2,7 +2,7 @@ You can stake tokens for CPU and/or NET bandwidth using `cleos` command line tool or using a wallet that implements this functionality. -TO DO: add link below -To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](how-to-stake-resource). +TO DO: verify and correct the next url +To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](https://eosio.github.io/eos/cleos/how-to-stake-resource) To stake tokens for CPU and/or NET bandwidth using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md index babb21955..d27cccac0 100644 --- a/docs/03_guides/04_how-to-vote.md +++ b/docs/03_guides/04_how-to-vote.md @@ -2,7 +2,7 @@ You can vote using `cleos` command line tool or using a wallet that implements the vote functionality. -TO DO: add link below -To vote using `cleos` check [how to vote](how-to-vote). +TO DO: verify and correct the next url +To vote using `cleos` check [how to vote](https://eosio.github.io/eos/cleos/how-to-vote) To vote using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file From 65a561ccbd9bc993e3f4e58f9f75be84de9a0a7c Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 22 Aug 2019 23:17:43 +0300 Subject: [PATCH 10/97] add index.md from introduction.md --- docs/{01_introduction.md => index.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{01_introduction.md => index.md} (100%) diff --git a/docs/01_introduction.md b/docs/index.md similarity index 100% rename from docs/01_introduction.md rename to docs/index.md From cf7f3f9b5f3c7145d471dbb6ad61a1671621960e Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 1 Sep 2019 21:55:29 -0400 Subject: [PATCH 11/97] prevent overflow within claimrewards in cases of extreme inflation; added eosio_system_tests/extreme_inflation test --- contracts/eosio.system/src/producer_pay.cpp | 1 + tests/eosio.system_tests.cpp | 37 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 28ec8f51f..aca711725 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -83,6 +83,7 @@ namespace eosiosystem { if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { int64_t new_tokens = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); + check( new_tokens >= 0, "overflow in calculating new tokens to be issued; inflation rate is too high" ); int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; int64_t to_savings = new_tokens - to_producers; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index e4bca563d..1eed42e40 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1525,6 +1525,43 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { } FC_LOG_AND_RETHROW() +BOOST_AUTO_TEST_CASE(extreme_inflation) try { + eosio_system_tester t(eosio_system_tester::setup_level::minimal); + symbol core_symbol{CORE_SYM}; + t.create_currency( N(eosio.token), config::system_account_name, asset((1ll << 62) - 1, core_symbol) ); + t.issue( asset(10000000000000, core_symbol) ); + t.deploy_contract(); + t.produce_block(); + t.create_account_with_resources(N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false); + BOOST_REQUIRE_EQUAL(t.success(), t.regproducer(N(defproducera))); + t.transfer( config::system_account_name, "defproducera", core_sym::from_string("200000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(t.success(), t.stake("defproducera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); + BOOST_REQUIRE_EQUAL(t.success(), t.vote( N(defproducera), { N(defproducera) })); + t.produce_blocks(4); + t.produce_block(fc::hours(24)); + + BOOST_REQUIRE_EQUAL(t.success(), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + t.produce_block(); + asset current_supply; + { + vector data = t.get_row_by_account( N(eosio.token), core_symbol.to_symbol_code().value, N(stat), core_symbol.to_symbol_code().value ); + current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, eosio_system_tester::abi_serializer_max_time)["supply"].template as(); + } + t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply ); + BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(std::numeric_limits::max(), 50000, 40000)); + t.produce_block(); + + t.produce_block(fc::hours(10*24)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + + t.produce_block(fc::hours(11*24)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("magnitude of asset amount must be less than 2^62"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + + t.produce_block(fc::hours(24)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("overflow in calculating new tokens to be issued; inflation rate is too high"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(500, 50000, 40000)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); +} FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { From 642450faaff17791709a15426110e565439cd3c8 Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 1 Sep 2019 23:02:22 -0400 Subject: [PATCH 12/97] handle overflow check properly (avoid undefined behavior) --- contracts/eosio.system/src/producer_pay.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index aca711725..b8403714c 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -82,8 +82,10 @@ namespace eosiosystem { const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { - int64_t new_tokens = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); - check( new_tokens >= 0, "overflow in calculating new tokens to be issued; inflation rate is too high" ); + double additional_inflation = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); + check( additional_inflation <= double(std::numeric_limits::max() - ((1ll << 10) - 1)), + "overflow in calculating new tokens to be issued; inflation rate is too high" ); + int64_t new_tokens = static_cast(additional_inflation); int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; int64_t to_savings = new_tokens - to_producers; From 6da7bece2cf0bc36867ef4abfcc244ea90e9651a Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 1 Sep 2019 23:19:22 -0400 Subject: [PATCH 13/97] ensure floating point math cannot possibly lead to a negative result --- contracts/eosio.system/src/producer_pay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index b8403714c..cf7e2ddeb 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -85,7 +85,7 @@ namespace eosiosystem { double additional_inflation = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); check( additional_inflation <= double(std::numeric_limits::max() - ((1ll << 10) - 1)), "overflow in calculating new tokens to be issued; inflation rate is too high" ); - int64_t new_tokens = static_cast(additional_inflation); + int64_t new_tokens = (additional_inflation < 0.0) ? 0 : static_cast(additional_inflation); int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; int64_t to_savings = new_tokens - to_producers; From 8f05770098794c040faf7b98cd966105b6c1ccf1 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Sep 2019 20:58:43 -0400 Subject: [PATCH 14/97] the minimum eosio.cdt dependency is now v1.7.x; this means that the is_feature_activated and preactivate_feature intrinsic definitions can be removed from the contracts --- CMakeLists.txt | 6 +-- README.md | 2 +- .../include/eosio.bios/eosio.bios.hpp | 41 ++++--------------- contracts/eosio.bios/src/eosio.bios.cpp | 8 ++-- contracts/eosio.msig/src/eosio.msig.cpp | 6 +-- .../include/eosio.system/native.hpp | 18 -------- contracts/eosio.system/src/native.cpp | 16 -------- pipeline.jsonc | 2 +- 8 files changed, 18 insertions(+), 81 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99738d46b..8ef311a3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts) set(VERSION_MAJOR 1) -set(VERSION_MINOR 8) +set(VERSION_MINOR 9) set(VERSION_PATCH 0) set(VERSION_SUFFIX rc1) @@ -19,8 +19,8 @@ find_package(eosio.cdt) message(STATUS "Building eosio.contracts v${VERSION_FULL}") -set(EOSIO_CDT_VERSION_MIN "1.6") -set(EOSIO_CDT_VERSION_SOFT_MAX "1.6") +set(EOSIO_CDT_VERSION_MIN "1.7") +set(EOSIO_CDT_VERSION_SOFT_MAX "1.7") #set(EOSIO_CDT_VERSION_HARD_MAX "") ### Check the version of eosio.cdt diff --git a/README.md b/README.md index 2b759f461..70bcafbfe 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](./contracts/eosio.token) Dependencies: -* [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.2) +* [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) * [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.1) (optional dependency only needed to build unit tests) To build contracts alone: diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 3fa4a4cdb..cadc70e8e 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -7,37 +7,6 @@ #include #include -// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` -#include - -namespace eosio { - namespace internal_use_do_not_use { - extern "C" { - __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); - - __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); - } - } -} - -namespace eosio { - bool is_feature_activated( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); - } - - void preactivate_feature( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); - } -} - /** * EOSIO Contracts * @@ -57,9 +26,13 @@ namespace eosio { * - eosio.token */ -namespace eosio { +namespace eosiobios { + using eosio::action_wrapper; + using eosio::check; + using eosio::checksum256; using eosio::ignore; + using eosio::name; using eosio::permission_level; using eosio::public_key; @@ -161,7 +134,7 @@ namespace eosio { * * @{ */ - class [[eosio::contract("eosio.bios")]] bios : public contract { + class [[eosio::contract("eosio.bios")]] bios : public eosio::contract { public: using contract::contract; /** @@ -420,4 +393,4 @@ namespace eosio { using reqactivated_action = action_wrapper<"reqactivated"_n, &bios::reqactivated>; }; /** @}*/ // end of @defgroup eosiobios eosio.bios -} /// namespace eosio +} /// namespace eosiobios diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index 8b9165cc7..582f03346 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,6 +1,6 @@ #include -namespace eosio { +namespace eosiobios { void bios::setabi( name account, const std::vector& abi ) { abi_hash_table table(get_self(), get_self().value); @@ -8,11 +8,11 @@ void bios::setabi( name account, const std::vector& abi ) { if( itr == table.end() ) { table.emplace( account, [&]( auto& row ) { row.owner = account; - row.hash = sha256(const_cast(abi.data()), abi.size()); + row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); }); } else { - table.modify( itr, same_payer, [&]( auto& row ) { - row.hash = sha256(const_cast(abi.data()), abi.size()); + table.modify( itr, eosio::same_payer, [&]( auto& row ) { + row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); }); } } diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 8fd75213d..176921929 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -30,8 +30,7 @@ void multisig::propose( ignore proposer, check( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); auto packed_requested = pack(_requested); - // TODO: Remove internal_use_do_not_use namespace after minimum eosio.cdt dependency becomes 1.7.x - auto res = internal_use_do_not_use::check_transaction_authorization( + auto res = check_transaction_authorization( trx_pos, size, (const char*)0, 0, packed_requested.data(), packed_requested.size() @@ -175,8 +174,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { old_apptable.erase(apps); } auto packed_provided_approvals = pack(approvals); - // TODO: Remove internal_use_do_not_use namespace after minimum eosio.cdt dependency becomes 1.7.x - auto res = internal_use_do_not_use::check_transaction_authorization( + auto res = check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), (const char*)0, 0, packed_provided_approvals.data(), packed_provided_approvals.size() diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 40a428504..854a05444 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -9,24 +9,6 @@ #include #include -// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` -#include - -namespace eosio { - namespace internal_use_do_not_use { - extern "C" { - __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); - - __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); - } - } - - bool is_feature_activated( const eosio::checksum256& feature_digest ); - void preactivate_feature( const eosio::checksum256& feature_digest ); -} - namespace eosiosystem { using eosio::checksum256; diff --git a/contracts/eosio.system/src/native.cpp b/contracts/eosio.system/src/native.cpp index a8f763040..df98daabf 100644 --- a/contracts/eosio.system/src/native.cpp +++ b/contracts/eosio.system/src/native.cpp @@ -2,22 +2,6 @@ #include -namespace eosio { - bool is_feature_activated( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); - } - - void preactivate_feature( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); - } -} - namespace eosiosystem { void native::onerror( ignore, ignore> ) { diff --git a/pipeline.jsonc b/pipeline.jsonc index ddf8f23b6..3b08495f8 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,7 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "release/1.8.x", - "eosio.cdt": "release/1.6.x" + "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } } From 327eab305c0aefff8448ccf28092f5ee555f103e Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 13:32:44 -0400 Subject: [PATCH 15/97] Fix issue where specifying commit would break grep. --- .cicd/helpers/dependency-info.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index f29ac1cb3..fe7a1e393 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -14,12 +14,14 @@ else exit 1 fi if [[ $TRAVIS ]]; then - CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match - EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match -else - CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match - EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match + AUTH="-H \"Authorization: token $key\"" fi + +# search GitHub for commit hash by tag and branch, preferring tag if both match +CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + +EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already From e69bcc591ce69ad1f9994a3176d384a88835f09e Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 13:45:23 -0400 Subject: [PATCH 16/97] Switch back to separate Travis command. --- .cicd/helpers/dependency-info.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index fe7a1e393..75a52bac6 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -13,15 +13,15 @@ else echo 'ERROR: No pipeline configuration file or dependencies file found!' exit 1 fi +# search GitHub for commit hash by tag and branch, preferring tag if both match if [[ $TRAVIS ]]; then - AUTH="-H \"Authorization: token $key\"" + CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') +else + CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') fi -# search GitHub for commit hash by tag and branch, preferring tag if both match -CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - -EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already From 1999854681d1f59973f7a346117287380664c23d Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 14:03:33 -0400 Subject: [PATCH 17/97] Cleanup of old auth variable. --- .cicd/helpers/dependency-info.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 75a52bac6..12bd6e9a8 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -15,11 +15,11 @@ else fi # search GitHub for commit hash by tag and branch, preferring tag if both match if [[ $TRAVIS ]]; then - CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') else - CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') fi test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already From da799f5293a67aa632a24ff06a521d55ed8c49f4 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 14:06:41 -0400 Subject: [PATCH 18/97] Remove whitespace. --- .cicd/helpers/dependency-info.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 12bd6e9a8..1ce31f3da 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -21,10 +21,8 @@ else CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') fi - test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." - export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt-ubuntu-18.04_amd64.deb" \ No newline at end of file From 03659bf07f54e757912d70f9c25c248da3e7459d Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:21:02 -0400 Subject: [PATCH 19/97] Remove empty lines --- .cicd/build.sh | 7 ------- .cicd/pipeline.yml | 1 - .cicd/tests.sh | 7 ------- 3 files changed, 15 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 98d27f1aa..96f3eaa71 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -1,20 +1,14 @@ #!/usr/bin/env bash set -eo pipefail - . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh - mkdir -p $BUILD_DIR - FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" - PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" - COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" - # Load BUILDKITE Environment Variables for use in docker run if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="" @@ -22,5 +16,4 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi - eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 870ae96c1..ab8bc6d9b 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -1,5 +1,4 @@ steps: - - wait - label: ":ubuntu: Ubuntu 18.04 - Build" diff --git a/.cicd/tests.sh b/.cicd/tests.sh index d421f4384..84115abb5 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -1,20 +1,14 @@ #!/usr/bin/env bash set -eo pipefail - . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh - mkdir -p $BUILD_DIR - FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" - PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" TEST_COMMANDS="ctest -j $JOBS" - COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" - # Load BUILDKITE Environment Variables for use in docker run if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="" @@ -22,5 +16,4 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi - eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file From afcebdb21e170dae7d39f865eecfcc0e9034c7db Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:22:48 -0400 Subject: [PATCH 20/97] Switch shebang from "#!/usr/bin/env bash" to "#!/bin/bash" for security reasons --- .cicd/build.sh | 2 +- .cicd/helpers/dependency-info.sh | 2 +- .cicd/tests.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 96f3eaa71..39eff4897 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/bash set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 1ce31f3da..d24f74b32 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/bash set -eo pipefail [[ "$RAW_PIPELINE_CONFIG" == '' ]] && export RAW_PIPELINE_CONFIG="$1" [[ "$RAW_PIPELINE_CONFIG" == '' ]] && export RAW_PIPELINE_CONFIG='pipeline.jsonc' diff --git a/.cicd/tests.sh b/.cicd/tests.sh index 84115abb5..d366fdbda 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/bash set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh From 74021e80a29eda5cdc9d647d1bb12186268b9140 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:31:25 -0400 Subject: [PATCH 21/97] Consistent command-step formatting --- .cicd/pipeline.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index ab8bc6d9b..ec851b437 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -2,9 +2,10 @@ steps: - wait - label: ":ubuntu: Ubuntu 18.04 - Build" - command: - - ./.cicd/build.sh - - "tar -pczf build.tar.gz build && buildkite-agent artifact upload build.tar.gz" + command: | + ./.cicd/build.sh + tar -pczf build.tar.gz build + buildkite-agent artifact upload build.tar.gz agents: queue: "automation-eos-builder-fleet" timeout: ${TIMEOUT:-10} @@ -13,9 +14,10 @@ steps: - wait - label: ":ubuntu: Ubuntu 18.04 - Test" - command: - - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' && tar -xzf build.tar.gz" - - ./.cicd/tests.sh + command: | + buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' + tar -xzf build.tar.gz + ./.cicd/tests.sh agents: queue: "automation-eos-builder-fleet" timeout: ${TIMEOUT:-10} From 49bd59909af71b4e92b3be20230ce73ebca08841 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:36:51 -0400 Subject: [PATCH 22/97] Add quotes to Buildkite variables --- .cicd/pipeline.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index ec851b437..c20d91d48 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -8,8 +8,8 @@ steps: buildkite-agent artifact upload build.tar.gz agents: queue: "automation-eos-builder-fleet" - timeout: ${TIMEOUT:-10} - skip: $SKIP_UBUNTU_18 + timeout: "${TIMEOUT:-10}" + skip: "$SKIP_UBUNTU_18" - wait @@ -20,8 +20,8 @@ steps: ./.cicd/tests.sh agents: queue: "automation-eos-builder-fleet" - timeout: ${TIMEOUT:-10} - skip: $SKIP_UBUNTU_18 + timeout: "${TIMEOUT:-10}" + skip: "$SKIP_UBUNTU_18" - wait: continue_on_failure: true From 027c8d8e69c212de54665f0c8767267b49ccb62b Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:41:13 -0400 Subject: [PATCH 23/97] Retry "docker pull" to protect against failures due to race conditions with eosio pipeline --- .cicd/build.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.cicd/build.sh b/.cicd/build.sh index 39eff4897..27a2b121b 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -16,4 +16,16 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi +# retry docker pull to protect against failures due to race conditions with eosio pipeline +INDEX='1' +echo "$ docker pull $FULL_TAG" +while [[ "$(docker pull $FULL_TAG 2>&1 | grep -ice "manifest for $FULL_TAG not found")" != '0' ]]; do + echo "ERROR: Docker image \"$FULL_TAG\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' + printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://eos-coverage.s3-us-west-2.amazonaws.com/build-$BUILDKITE_BUILD_NUMBER/code-coverage-report/index.html;content=here\a for this container to exist.\n" + echo "Attempt $INDEX, retry in 60 seconds..." + echo '' + INDEX=$(( $INDEX + 1 )) + sleep 60 +done +# run eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file From b3db2046fcbeed14f105b9572504740927eeab2a Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:58:42 -0400 Subject: [PATCH 24/97] Increase build step timeout from 10 to 40 minutes --- .cicd/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index c20d91d48..4ea9722bb 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -8,7 +8,7 @@ steps: buildkite-agent artifact upload build.tar.gz agents: queue: "automation-eos-builder-fleet" - timeout: "${TIMEOUT:-10}" + timeout: "${TIMEOUT:-40}" skip: "$SKIP_UBUNTU_18" - wait From ebccfee8b176b33be4e3717ce02685ea58b3166d Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:36:47 -0400 Subject: [PATCH 25/97] Always use the same container to build and test --- .cicd/build.sh | 1 + .cicd/tests.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 27a2b121b..7c99994bb 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -4,6 +4,7 @@ set -eo pipefail . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} +buildkite-agent meta-data set docker-image "$FULL_TAG" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" diff --git a/.cicd/tests.sh b/.cicd/tests.sh index d366fdbda..9f87e59ca 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -3,7 +3,7 @@ set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR -FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} +FULL_TAG="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" From 8e2284d5c048e4c281c185657e89ecf1202b7e36 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:39:23 -0400 Subject: [PATCH 26/97] Rename tests.sh to test.sh for consistency --- .cicd/pipeline.yml | 2 +- .cicd/{tests.sh => test.sh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename .cicd/{tests.sh => test.sh} (100%) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 4ea9722bb..009fe0ef9 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -17,7 +17,7 @@ steps: command: | buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' tar -xzf build.tar.gz - ./.cicd/tests.sh + ./.cicd/test.sh agents: queue: "automation-eos-builder-fleet" timeout: "${TIMEOUT:-10}" diff --git a/.cicd/tests.sh b/.cicd/test.sh similarity index 100% rename from .cicd/tests.sh rename to .cicd/test.sh From d8ed1ec6f23011997f6222d328aba4aed82537e9 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:42:04 -0400 Subject: [PATCH 27/97] Rename FULL_TAG to DOCKER_IMAGE for clarity --- .cicd/build.sh | 12 ++++++------ .cicd/test.sh | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 7c99994bb..e2df3a87b 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -3,8 +3,8 @@ set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR -FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} -buildkite-agent meta-data set docker-image "$FULL_TAG" +DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} +buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" @@ -19,9 +19,9 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then fi # retry docker pull to protect against failures due to race conditions with eosio pipeline INDEX='1' -echo "$ docker pull $FULL_TAG" -while [[ "$(docker pull $FULL_TAG 2>&1 | grep -ice "manifest for $FULL_TAG not found")" != '0' ]]; do - echo "ERROR: Docker image \"$FULL_TAG\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' +echo "$ docker pull $DOCKER_IMAGE" +while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMAGE not found")" != '0' ]]; do + echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://eos-coverage.s3-us-west-2.amazonaws.com/build-$BUILDKITE_BUILD_NUMBER/code-coverage-report/index.html;content=here\a for this container to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' @@ -29,4 +29,4 @@ while [[ "$(docker pull $FULL_TAG 2>&1 | grep -ice "manifest for $FULL_TAG not f sleep 60 done # run -eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/test.sh b/.cicd/test.sh index 9f87e59ca..4bc918438 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -3,7 +3,7 @@ set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR -FULL_TAG="$(buildkite-agent meta-data get docker-image)" +DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" @@ -16,4 +16,4 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi -eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file From 7824efe7e441981c94216efc8eabd74d8da951bc Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:58:48 -0400 Subject: [PATCH 28/97] Move Buildkite environment loading into function --- .cicd/build.sh | 10 ++-------- .cicd/helpers/buildkite.sh | 11 +++++++++++ .cicd/test.sh | 10 ++-------- 3 files changed, 15 insertions(+), 16 deletions(-) create mode 100755 .cicd/helpers/buildkite.sh diff --git a/.cicd/build.sh b/.cicd/build.sh index e2df3a87b..4a32d65c3 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -1,5 +1,6 @@ #!/bin/bash set -eo pipefail +. ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR @@ -10,13 +11,6 @@ CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dp PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" -# Load BUILDKITE Environment Variables for use in docker run -if [[ -f $BUILDKITE_ENV_FILE ]]; then - evars="" - while read -r var; do - evars="$evars --env ${var%%=*}" - done < "$BUILDKITE_ENV_FILE" -fi # retry docker pull to protect against failures due to race conditions with eosio pipeline INDEX='1' echo "$ docker pull $DOCKER_IMAGE" @@ -29,4 +23,4 @@ while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMA sleep 60 done # run -eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/helpers/buildkite.sh b/.cicd/helpers/buildkite.sh new file mode 100755 index 000000000..1d2eee398 --- /dev/null +++ b/.cicd/helpers/buildkite.sh @@ -0,0 +1,11 @@ +# load buildkite intrinsic environment variables for use in docker run +function buildkite-intrinsics() +{ + BK_ENV='' + if [[ -f $BUILDKITE_ENV_FILE ]]; then + while read -r var; do + BK_ENV="$BK_ENV --env ${var%%=*}" + done < "$BUILDKITE_ENV_FILE" + fi + echo "$BK_ENV" +} \ No newline at end of file diff --git a/.cicd/test.sh b/.cicd/test.sh index 4bc918438..b54d1fac1 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -1,5 +1,6 @@ #!/bin/bash set -eo pipefail +. ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR @@ -9,11 +10,4 @@ CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dp PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" TEST_COMMANDS="ctest -j $JOBS" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" -# Load BUILDKITE Environment Variables for use in docker run -if [[ -f $BUILDKITE_ENV_FILE ]]; then - evars="" - while read -r var; do - evars="$evars --env ${var%%=*}" - done < "$BUILDKITE_ENV_FILE" -fi -eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file From a5474d70d270f078308b95aaf2957f255e7ed801 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 11:36:03 -0400 Subject: [PATCH 29/97] Remove dependency-info.sh from test.sh --- .cicd/test.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.cicd/test.sh b/.cicd/test.sh index b54d1fac1..836494def 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -2,7 +2,6 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh -. ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} From a14ed3b07dea7eafd68a6b96cebd413ae2c6c90d Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 11:43:27 -0400 Subject: [PATCH 30/97] Revert "Remove dependency-info.sh from test.sh" as it is needed for CDT installation This reverts commit a5474d70d270f078308b95aaf2957f255e7ed801. --- .cicd/test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.cicd/test.sh b/.cicd/test.sh index 836494def..b54d1fac1 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -2,6 +2,7 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh +. ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} From fa8d8ea78d76410950efe65b5d4a9eb20a3a0fc4 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 11:56:50 -0400 Subject: [PATCH 31/97] Fix Buildkite URL in Docker pull retry message --- .cicd/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 4a32d65c3..acc2c4a60 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -16,7 +16,7 @@ INDEX='1' echo "$ docker pull $DOCKER_IMAGE" while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMAGE not found")" != '0' ]]; do echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' - printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://eos-coverage.s3-us-west-2.amazonaws.com/build-$BUILDKITE_BUILD_NUMBER/code-coverage-report/index.html;content=here\a for this container to exist.\n" + printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio/builds?commit=$BUILDKITE_COMMIT;content=here\a for this container to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' INDEX=$(( $INDEX + 1 )) From 0c1e13ce7841e93317dfa4a1a448d48cc517c043 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 13:16:53 -0400 Subject: [PATCH 32/97] Use the EOSIO_COMMIT for the URL, not the BUILDKITE_COMMIT --- .cicd/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index acc2c4a60..721df2c50 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -16,7 +16,7 @@ INDEX='1' echo "$ docker pull $DOCKER_IMAGE" while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMAGE not found")" != '0' ]]; do echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' - printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio/builds?commit=$BUILDKITE_COMMIT;content=here\a for this container to exist.\n" + printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio/builds?commit=$EOSIO_COMMIT;content=here\a for this container to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' INDEX=$(( $INDEX + 1 )) From d8e19380bbaf545548211072b89b5ea4e14f1eb9 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 13:21:57 -0400 Subject: [PATCH 33/97] Use the same CDT binary for both the build and test step --- .cicd/build.sh | 2 ++ .cicd/test.sh | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 721df2c50..c8519bb6f 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -6,6 +6,8 @@ set -eo pipefail mkdir -p $BUILD_DIR DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" +buildkite-agent meta-data set cdt-url "$CDT_URL" +buildkite-agent meta-data set cdt-version "$CDT_VERSION" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" diff --git a/.cicd/test.sh b/.cicd/test.sh index b54d1fac1..4eaecffaa 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -2,8 +2,9 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh -. ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR +CDT_URL="$(buildkite-agent meta-data get cdt-url)" +CDT_VERSION="$(buildkite-agent meta-data get cdt-version)" DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" From a75612498a8d76c85ea21827e52594d574eacbb3 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 15:29:23 -0400 Subject: [PATCH 34/97] Export dependency and Docker information as variables on Travis --- .cicd/build.sh | 12 +++++++++--- .cicd/test.sh | 8 +++++--- .travis.yml | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index c8519bb6f..bf97c186b 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -5,9 +5,15 @@ set -eo pipefail . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} -buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" -buildkite-agent meta-data set cdt-url "$CDT_URL" -buildkite-agent meta-data set cdt-version "$CDT_VERSION" +if [[ "$BUILDKITE" == 'true' ]]; then + buildkite-agent meta-data set cdt-url "$CDT_URL" + buildkite-agent meta-data set cdt-version "$CDT_VERSION" + buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" +else + export CDT_URL + export CDT_VERSION + export DOCKER_IMAGE +fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" diff --git a/.cicd/test.sh b/.cicd/test.sh index 4eaecffaa..521530199 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -3,9 +3,11 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh mkdir -p $BUILD_DIR -CDT_URL="$(buildkite-agent meta-data get cdt-url)" -CDT_VERSION="$(buildkite-agent meta-data get cdt-version)" -DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" +if [[ "$BUILDKITE" == 'true' ]]; then + CDT_URL="$(buildkite-agent meta-data get cdt-url)" + CDT_VERSION="$(buildkite-agent meta-data get cdt-version)" + DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" +fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" diff --git a/.travis.yml b/.travis.yml index fd9aeb346..57b617af2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ matrix: - os: linux dist: xenial services: docker -script: "./.cicd/build.sh && ./.cicd/tests.sh" +script: ". ./.cicd/build.sh && ./.cicd/tests.sh" notifications: webhooks: secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= From cbc4f3a4b59145c99485e73645833308897cbdf1 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 15:50:03 -0400 Subject: [PATCH 35/97] Fix travis.yml test invocation --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 57b617af2..516355254 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ matrix: - os: linux dist: xenial services: docker -script: ". ./.cicd/build.sh && ./.cicd/tests.sh" +script: ". ./.cicd/build.sh && ./.cicd/test.sh" notifications: webhooks: secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= From 22dac816140da101ec11c98503564a268b4f0f48 Mon Sep 17 00:00:00 2001 From: Sandwich <“dskvr@users.noreply.github.com”> Date: Thu, 26 Sep 2019 14:59:25 +0200 Subject: [PATCH 36/97] Had to make some modifications to some of the inline comments so they would not be picked up by mdjavadoc, which we are temporarily using until we can get standardese to correctly parse the documentation on eosio.contracts --- .../include/eosio.system/eosio.system.hpp | 142 +++++++----------- 1 file changed, 53 insertions(+), 89 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index b98db3525..d2903efd2 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -74,9 +74,6 @@ namespace eosiosystem { static constexpr int64_t default_votepay_factor = 4; // 25% of the producer pay /** - * - * @defgroup eosiosystem eosio.system - * @ingroup eosiocontracts * eosio.system contract defines the structures and actions needed for blockchain's core functionality. * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or * delegate their vote to a proxy. @@ -88,13 +85,11 @@ namespace eosiosystem { * @{ */ - /** - * A name bid, which consists of: - * - a `newname` name that the bid is for - * - a `high_bidder` account name that is the one with the highest bid so far - * - the `high_bid` which is amount of highest bid - * - and `last_bid_time` which is the time of the highest bid - */ + // A name bid, which consists of: + // - a `newname` name that the bid is for + // - a `high_bidder` account name that is the one with the highest bid so far + // - the `high_bid` which is amount of highest bid + // - and `last_bid_time` which is the time of the highest bid struct [[eosio::table, eosio::contract("eosio.system")]] name_bid { name newname; name high_bidder; @@ -105,11 +100,9 @@ namespace eosiosystem { uint64_t by_high_bid()const { return static_cast(-high_bid); } }; - /** - * A bid refund, which is defined by: - * - the `bidder` account name owning the refund - * - the `amount` to be refunded - */ + // A bid refund, which is defined by: + // - the `bidder` account name owning the refund + // - the `amount` to be refunded struct [[eosio::table, eosio::contract("eosio.system")]] bid_refund { name bidder; asset amount; @@ -122,9 +115,7 @@ namespace eosiosystem { typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; - /** - * Defines new global state parameters. - */ + // Defines new global state parameters. struct [[eosio::table("global"), eosio::contract("eosio.system")]] eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } @@ -151,9 +142,7 @@ namespace eosiosystem { (last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) }; - /** - * Defines new global state parameters added after version 1.0 - */ + // Defines new global state parameters added after version 1.0 struct [[eosio::table("global2"), eosio::contract("eosio.system")]] eosio_global_state2 { eosio_global_state2(){} @@ -167,9 +156,7 @@ namespace eosiosystem { (total_producer_votepay_share)(revision) ) }; - /** - * Defines new global state parameters added after version 1.3.0 - */ + // Defines new global state parameters added after version 1.3.0 struct [[eosio::table("global3"), eosio::contract("eosio.system")]] eosio_global_state3 { eosio_global_state3() { } time_point last_vpay_state_update; @@ -178,9 +165,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) }; - /** - * Defines new global state parameters to store inflation rate and distribution - */ + // Defines new global state parameters to store inflation rate and distribution struct [[eosio::table("global4"), eosio::contract("eosio.system")]] eosio_global_state4 { eosio_global_state4() { } double continuous_rate; @@ -190,9 +175,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state4, (continuous_rate)(inflation_pay_factor)(votepay_factor) ) }; - /** - * Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 - */ + // Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { name owner; double total_votes = 0; @@ -213,9 +196,7 @@ namespace eosiosystem { (unpaid_blocks)(last_claim_time)(location) ) }; - /** - * Defines new producer info structure to be stored in new producer info table, added after version 1.3.0 - */ + // Defines new producer info structure to be stored in new producer info table, added after version 1.3.0 struct [[eosio::table, eosio::contract("eosio.system")]] producer_info2 { name owner; double votepay_share = 0; @@ -227,30 +208,23 @@ namespace eosiosystem { EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) }; - /** - * Voter info. Voter info stores information about the voter: - * - `owner` the voter - * - `proxy` the proxy set by the voter, if any - * - `producers` the producers approved by this voter if no proxy set - * - `staked` the amount staked - */ + // Voter info. Voter info stores information about the voter: + // - `owner` the voter + // - `proxy` the proxy set by the voter, if any + // - `producers` the producers approved by this voter if no proxy set + // - `staked` the amount staked struct [[eosio::table, eosio::contract("eosio.system")]] voter_info { name owner; /// the voter name proxy; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set int64_t staked = 0; - /** - * Every time a vote is cast we must first "undo" the last vote weight, before casting the - * new vote weight. Vote weight is calculated as: - * - * stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) - */ + // Every time a vote is cast we must first "undo" the last vote weight, before casting the + // new vote weight. Vote weight is calculated as: + // stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) double last_vote_weight = 0; /// the vote weight cast the last time the vote was updated - /** - * Total vote weight delegated to this voter. - */ + // Total vote weight delegated to this voter. double proxied_vote_weight= 0; /// the total vote weight delegated to this voter as a proxy bool is_proxy = 0; /// whether the voter is a proxy for others @@ -303,9 +277,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(ram_bytes) ) }; - /** - * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. - */ + // Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. struct [[eosio::table, eosio::contract("eosio.system")]] delegated_bandwidth { name from; name to; @@ -338,17 +310,15 @@ namespace eosiosystem { typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; - /** - * `rex_pool` structure underlying the rex pool table. A rex pool table entry is defined by: - * - `version` defaulted to zero, - * - `total_lent` total amount of CORE_SYMBOL in open rex_loans - * - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), - * - `total_rent` fees received in exchange for lent (connector), - * - `total_lendable` total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent), - * - `total_rex` total number of REX shares allocated to contributors to total_lendable, - * - `namebid_proceeds` the amount of CORE_SYMBOL to be transferred from namebids to REX pool, - * - `loan_num` increments with each new loan. - */ + // `rex_pool` structure underlying the rex pool table. A rex pool table entry is defined by: + // - `version` defaulted to zero, + // - `total_lent` total amount of CORE_SYMBOL in open rex_loans + // - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), + // - `total_rent` fees received in exchange for lent (connector), + // - `total_lendable` total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent), + // - `total_rex` total number of REX shares allocated to contributors to total_lendable, + // - `namebid_proceeds` the amount of CORE_SYMBOL to be transferred from namebids to REX pool, + // - `loan_num` increments with each new loan struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { uint8_t version = 0; asset total_lent; @@ -364,12 +334,10 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; - /** - * `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: - * - `version` defaulted to zero, - * - `owner` the owner of the rex fund, - * - `balance` the balance of the fund. - */ + // `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: + // - `version` defaulted to zero, + // - `owner` the owner of the rex fund, + // - `balance` the balance of the fund. struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { uint8_t version = 0; name owner; @@ -380,14 +348,12 @@ namespace eosiosystem { typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; - /** - * `rex_balance` structure underlying the rex balance table. A rex balance table entry is defined by: - * - `version` defaulted to zero, - * - `owner` the owner of the rex fund, - * - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, - * - `rex_balance` the amount of REX owned by owner, - * - `matured_rex` matured REX available for selling. - */ + // `rex_balance` structure underlying the rex balance table. A rex balance table entry is defined by: + // - `version` defaulted to zero, + // - `owner` the owner of the rex fund, + // - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, + // - `rex_balance` the amount of REX owned by owner, + // - `matured_rex` matured REX available for selling struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { uint8_t version = 0; name owner; @@ -401,18 +367,16 @@ namespace eosiosystem { typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; - /** - * `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. A rex net/cpu loan table entry is defined by: - * - `version` defaulted to zero, - * - `from` account creating and paying for loan, - * - `receiver` account receiving rented resources, - * - `payment` SYS tokens paid for the loan, - * - `balance` is the amount of SYS tokens available to be used for loan auto-renewal, - * - `total_staked` total amount staked, - * - `loan_num` loan number/id, - * - `expiration` the expiration time when loan will be either closed or renewed - * If payment <= balance, the loan is renewed, and closed otherwise. - */ + // `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. A rex net/cpu loan table entry is defined by: + // - `version` defaulted to zero, + // - `from` account creating and paying for loan, + // - `receiver` account receiving rented resources, + // - `payment` SYS tokens paid for the loan, + // - `balance` is the amount of SYS tokens available to be used for loan auto-renewal, + // - `total_staked` total amount staked, + // - `loan_num` loan number/id, + // - `expiration` the expiration time when loan will be either closed or renewed + // If payment <= balance, the loan is renewed, and closed otherwise. struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { uint8_t version = 0; name from; From f7eb4f77fefa9bb4ca111859cb5474fcbbe6da43 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 27 Sep 2019 20:47:46 -0400 Subject: [PATCH 37/97] the minimum eosio dependency is now v2.0.x; update tests to work with eosio v2.0.x --- README.md | 2 +- pipeline.jsonc | 2 +- tests/CMakeLists.txt | 4 +- tests/eosio.msig_tests.cpp | 62 +++++++++++------- tests/eosio.system_tester.hpp | 105 ++++++++++++++++++++++++++---- tests/eosio.system_tests.cpp | 119 +++++++++++++++++----------------- tests/eosio.token_tests.cpp | 6 +- tests/eosio.wrap_tests.cpp | 22 +++---- 8 files changed, 210 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index 70bcafbfe..52663847d 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The following unprivileged contract(s) are also part of the system. Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) -* [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.1) (optional dependency only needed to build unit tests) +* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) (optional dependency only needed to build unit tests) To build contracts alone: 1. Ensure an appropriate version of eosio.cdt is installed. Installing eosio.cdt from binaries is sufficient. diff --git a/pipeline.jsonc b/pipeline.jsonc index 3b08495f8..c06f57fce 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,7 +4,7 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "release/1.8.x", + "eosio": "26ed54d90f4e5436faac7fda0f6a0eabbbccc6e2", // eventually update to release/2.0.x "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a14236482..2048afffb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 3.5 ) -set(EOSIO_VERSION_MIN "1.8") -set(EOSIO_VERSION_SOFT_MAX "1.8") +set(EOSIO_VERSION_MIN "2.0") +set(EOSIO_VERSION_SOFT_MAX "2.0") #set(EOSIO_VERSION_HARD_MAX "") find_package(eosio) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index e28e229c0..cbc614b9f 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -181,7 +181,7 @@ transaction eosio_msig_tester::reqauth( account_name from, const vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); + auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -313,7 +313,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { - auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); + auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); //try with not enough requested auth BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -406,10 +406,17 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) // / | \ <--- implicitly updated in onblock action // alice active bob active carol active - set_authority(N(eosio), "active", authority(1, - vector{{get_private_key("eosio", "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}}), "owner", - { { N(eosio), "active" } }, { get_private_key( N(eosio), "active" ) }); + set_authority( + config::system_account_name, + config::active_name, + authority( 1, + vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, + vector{{{N(eosio.prods), config::active_name}, 1}} + ), + config::owner_name, + {{config::system_account_name, config::active_name}}, + {get_private_key(config::system_account_name, "active")} + ); set_producers( {N(alice),N(bob),N(carol)} ); produce_blocks(50); @@ -421,7 +428,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); issue(config::system_account_name, core_sym::from_string("1000000000.0000")); BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); @@ -436,7 +443,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, {N(carol), config::active_name} }; @@ -524,10 +531,17 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ) try { // set up the link between (eosio active) and (eosio.prods active) - set_authority(N(eosio), "active", authority(1, - vector{{get_private_key("eosio", "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}}), "owner", - { { N(eosio), "active" } }, { get_private_key( N(eosio), "active" ) }); + set_authority( + config::system_account_name, + config::active_name, + authority( 1, + vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, + vector{{{N(eosio.prods), config::active_name}, 1}} + ), + config::owner_name, + {{config::system_account_name, config::active_name}}, + {get_private_key(config::system_account_name, "active")} + ); create_accounts( { N(apple) } ); set_producers( {N(alice),N(bob),N(carol), N(apple)} ); @@ -539,7 +553,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); issue(config::system_account_name, core_sym::from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( "eosio" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( config::system_account_name ) ); set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); @@ -555,7 +569,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, {N(carol), config::active_name}, {N(apple), config::active_name}}; @@ -653,7 +667,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -696,7 +710,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( propose_invalidate_approve, eosio_msig_tester ) try { - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -752,7 +766,7 @@ BOOST_FIXTURE_TEST_CASE( approve_execute_old, eosio_msig_tester ) try { produce_blocks(); //propose with old version of eosio.msig - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -797,7 +811,7 @@ BOOST_FIXTURE_TEST_CASE( approve_unapprove_old, eosio_msig_tester ) try { produce_blocks(); //propose with old version of eosio.msig - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -839,7 +853,7 @@ BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); produce_blocks(); - auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); + auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -895,7 +909,7 @@ BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); auto trx_hash = fc::sha256::hash( trx ); auto not_trx_hash = fc::sha256::hash( trx_hash ); @@ -944,7 +958,7 @@ BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( switch_proposal_and_fail_approve_with_hash, eosio_msig_tester ) try { - auto trx1 = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx1 = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); auto trx1_hash = fc::sha256::hash( trx1 ); push_action( N(alice), N(propose), mvo() @@ -954,7 +968,7 @@ BOOST_FIXTURE_TEST_CASE( switch_proposal_and_fail_approve_with_hash, eosio_msig_ ("requested", vector{{ N(alice), config::active_name }}) ); - auto trx2 = reqauth("alice", + auto trx2 = reqauth( N(alice), { permission_level{N(alice), config::active_name}, permission_level{N(alice), config::owner_name} }, abi_serializer_max_time ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 179d4b0fa..753df1a1f 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -23,9 +23,9 @@ using mvo = fc::mutable_variant_object; #endif #endif - namespace eosio_system { + class eosio_system_tester : public TESTER { public: @@ -249,13 +249,23 @@ class eosio_system_tester : public TESTER { action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { return push_action( payer, N(buyram), mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); } + action_result buyram( std::string_view payer, std::string_view receiver, const asset& eosin ) { + return buyram( account_name(payer), account_name(receiver), eosin ); + } + action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { return push_action( payer, N(buyrambytes), mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); } + action_result buyrambytes( std::string_view payer, std::string_view receiver, uint32_t numbytes ) { + return buyrambytes( account_name(payer), account_name(receiver), numbytes ); + } action_result sellram( const account_name& account, uint64_t numbytes ) { return push_action( account, N(sellram), mvo()( "account", account)("bytes",numbytes) ); } + action_result sellram( std::string_view account, uint64_t numbytes ) { + return sellram( account_name(account), numbytes ); + } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { string action_type_name = abi_ser.get_action_type(name); @@ -265,7 +275,7 @@ class eosio_system_tester : public TESTER { act.name = name; act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); } action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { @@ -277,10 +287,16 @@ class eosio_system_tester : public TESTER { ("transfer", 0 ) ); } + action_result stake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { + return stake( account_name(from), account_name(to), net, cpu ); + } action_result stake( const account_name& acnt, const asset& net, const asset& cpu ) { return stake( acnt, acnt, net, cpu ); } + action_result stake( std::string_view acnt, const asset& net, const asset& cpu ) { + return stake( account_name(acnt), net, cpu ); + } action_result stake_with_transfer( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), N(delegatebw), mvo() @@ -291,10 +307,16 @@ class eosio_system_tester : public TESTER { ("transfer", true ) ); } + action_result stake_with_transfer( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { + return stake_with_transfer( account_name(from), account_name(to), net, cpu ); + } action_result stake_with_transfer( const account_name& acnt, const asset& net, const asset& cpu ) { return stake_with_transfer( acnt, acnt, net, cpu ); } + action_result stake_with_transfer( std::string_view acnt, const asset& net, const asset& cpu ) { + return stake_with_transfer( account_name(acnt), net, cpu ); + } action_result unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), N(undelegatebw), mvo() @@ -304,10 +326,16 @@ class eosio_system_tester : public TESTER { ("unstake_cpu_quantity", cpu) ); } + action_result unstake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { + return unstake( account_name(from), account_name(to), net, cpu ); + } action_result unstake( const account_name& acnt, const asset& net, const asset& cpu ) { return unstake( acnt, acnt, net, cpu ); } + action_result unstake( std::string_view acnt, const asset& net, const asset& cpu ) { + return unstake( account_name(acnt), net, cpu ); + } int64_t bancor_convert( int64_t S, int64_t R, int64_t T ) { return double(R) * T / ( double(S) + T ); }; @@ -565,7 +593,7 @@ class eosio_system_tester : public TESTER { fc::variant get_loan_info( const uint64_t& loan_num, bool cpu ) const { name table_name = cpu ? N(cpuloan) : N(netloan); - vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, loan_num ); + vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, account_name(loan_num) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer_max_time ); } @@ -669,6 +697,9 @@ class eosio_system_tester : public TESTER { ("bid", bid) ); } + action_result bidname( std::string_view bidder, std::string_view newname, const asset& bid ) { + return bidname( account_name(bidder), account_name(newname), bid ); + } static fc::variant_object producer_parameters_example( int n ) { return mutable_variant_object() @@ -710,35 +741,54 @@ class eosio_system_tester : public TESTER { ("proxy", proxy) ("producers", producers)); } + action_result vote( const account_name& voter, const std::vector& producers, std::string_view proxy ) { + return vote( voter, producers, account_name(proxy) ); + } uint32_t last_block_time() const { return time_point_sec( control->head_block_time() ).sec_since_epoch(); } asset get_balance( const account_name& act, symbol balance_symbol = symbol{CORE_SYM} ) { - vector data = get_row_by_account( N(eosio.token), act, N(accounts), balance_symbol.to_symbol_code().value ); + vector data = get_row_by_account( N(eosio.token), act, N(accounts), account_name(balance_symbol.to_symbol_code().value) ); return data.empty() ? asset(0, balance_symbol) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } + asset get_balance( std::string_view act, symbol balance_symbol = symbol{CORE_SYM} ) { + return get_balance( account_name(act), balance_symbol ); + } + fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); } + fc::variant get_total_stake( std::string_view act ) { + return get_total_stake( account_name(act) ); + } fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); } + fc::variant get_voter_info( std::string_view act ) { + return get_voter_info( account_name(act) ); + } fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); } + fc::variant get_producer_info( std::string_view act ) { + return get_producer_info( account_name(act) ); + } fc::variant get_producer_info2( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers2), act ); return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer_max_time ); } + fc::variant get_producer_info2( std::string_view act ) { + return get_producer_info2( account_name(act) ); + } void create_currency( name contract, name manager, asset maxsupply ) { auto act = mutable_variant_object() @@ -765,6 +815,18 @@ class eosio_system_tester : public TESTER { ); } + void transfer( const name& from, std::string_view to, const asset& amount, const name& manager = config::system_account_name ) { + transfer( from, name(to), amount, manager ); + } + + void transfer( std::string_view from, std::string_view to, const asset& amount, std::string_view manager ) { + transfer( name(from), name(to), amount, name(manager) ); + } + + void transfer( std::string_view from, std::string_view to, const asset& amount ) { + transfer( name(from), name(to), amount ); + } + void issue_and_transfer( const name& to, const asset& amount, const name& manager = config::system_account_name ) { signed_transaction trx; trx.actions.emplace_back( get_action( N(eosio.token), N(issue), @@ -791,6 +853,18 @@ class eosio_system_tester : public TESTER { push_transaction( trx ); } + void issue_and_transfer( std::string_view to, const asset& amount, std::string_view manager ) { + issue_and_transfer( name(to), amount, name(manager) ); + } + + void issue_and_transfer( std::string_view to, const asset& amount, const name& manager ) { + issue_and_transfer( name(to), amount, manager); + } + + void issue_and_transfer( std::string_view to, const asset& amount ) { + issue_and_transfer( name(to), amount ); + } + double stake2votes( asset stake ) { auto now = control->pending_block_time().time_since_epoch().count() / 1000000; return stake.get_amount() * pow(2, int64_t((now - (config::block_timestamp_epoch / 1000)) / (86400 * 7))/ double(52) ); // 52 week periods (i.e. ~years) @@ -803,7 +877,7 @@ class eosio_system_tester : public TESTER { fc::variant get_stats( const string& symbolname ) { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); + vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } @@ -840,7 +914,7 @@ class eosio_system_tester : public TESTER { abi_serializer msig_abi_ser; { create_account_with_resources( N(eosio.msig), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( "eosio", "eosio.msig", core_sym::from_string("5000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( N(eosio), N(eosio.msig), core_sym::from_string("5000.0000") ) ); produce_block(); auto trace = base_tester::push_action(config::system_account_name, N(setpriv), @@ -863,8 +937,8 @@ class eosio_system_tester : public TESTER { vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain - transfer( "eosio", "alice1111111", core_sym::from_string("650000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); + transfer( N(eosio), N(alice1111111), core_sym::from_string("650000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), N(alice1111111), core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers std::vector producer_names; @@ -896,9 +970,9 @@ class eosio_system_tester : public TESTER { //vote for producers { - transfer( config::system_account_name, "alice1111111", core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake( "alice1111111", core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("30000000.0000") ) ); + transfer( config::system_account_name, N(alice1111111), core_sym::from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake( N(alice1111111), core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(success(), buyram( N(alice1111111), N(alice1111111), core_sym::from_string("30000000.0000") ) ); BOOST_REQUIRE_EQUAL(success(), push_action(N(alice1111111), N(voteproducer), mvo() ("voter", "alice1111111") ("proxy", name(0).to_string()) @@ -981,14 +1055,23 @@ inline fc::mutable_variant_object voter( account_name acct ) { ("is_proxy", 0) ; } +inline fc::mutable_variant_object voter( std::string_view acct ) { + return voter( account_name(acct) ); +} inline fc::mutable_variant_object voter( account_name acct, const asset& vote_stake ) { return voter( acct )( "staked", vote_stake.get_amount() ); } +inline fc::mutable_variant_object voter( std::string_view acct, const asset& vote_stake ) { + return voter( account_name(acct), vote_stake ); +} inline fc::mutable_variant_object voter( account_name acct, int64_t vote_stake ) { return voter( acct )( "staked", vote_stake ); } +inline fc::mutable_variant_object voter( std::string_view acct, int64_t vote_stake ) { + return voter( account_name(acct), vote_stake ); +} inline fc::mutable_variant_object proxy( account_name acct ) { return voter( acct )( "is_proxy", 1 ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 1eed42e40..ce51882f1 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -126,17 +126,17 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); BOOST_REQUIRE_EQUAL( false, get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), symbol{SY(4,RAMCORE)}.value() ).empty() ); + N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ).empty() ); auto get_ram_market = [this]() -> fc::variant { vector data = get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), symbol{SY(4,RAMCORE)}.value() ); + N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ); BOOST_REQUIRE( !data.empty() ); return abi_ser.binary_to_variant("exchange_state", data, abi_serializer_max_time); }; { - transfer( config::system_account_name, "alice1111111", core_sym::from_string("10000000.0000"), config::system_account_name ); + transfer( config::system_account_name, N(alice1111111), core_sym::from_string("10000000.0000"), config::system_account_name ); uint64_t bytes0 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); auto market = get_ram_market(); @@ -157,7 +157,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { } { - transfer( config::system_account_name, "bob111111111", core_sym::from_string("100000.0000"), config::system_account_name ); + transfer( config::system_account_name, N(bob111111111), core_sym::from_string("100000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must reserve a positive amount"), buyrambytes( "bob111111111", "bob111111111", 1 ) ); @@ -246,7 +246,7 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try //eosio stakes for alice with transfer flag transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //check that alice has both bandwidth and voting power auto total = get_total_stake("alice1111111"); @@ -287,7 +287,7 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() @@ -298,7 +298,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot use transfer flag if delegating to self"), - stake_with_transfer( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) + stake_with_transfer( N(alice1111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() @@ -310,7 +310,7 @@ BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { //eosio stakes for alice with transfer flag transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //check that alice has both bandwidth and voting power auto total = get_total_stake("alice1111111"); @@ -351,7 +351,7 @@ BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() @@ -634,7 +634,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("250.0000") ), get_voter_info( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); - auto refund = get_refund_request( "alice1111111" ); + auto refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); //XXX auto request_time = refund["request_time"].as_int64(); @@ -646,7 +646,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("350.0000") ), get_voter_info( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); @@ -655,7 +655,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("50.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("25.0000"), refund["cpu_amount"].as() ); //request time should stay the same @@ -669,7 +669,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); //pending refund should be removed - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_TEST_REQUIRE( refund.is_null() ); //balance should stay the same BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); @@ -680,7 +680,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); @@ -690,7 +690,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("700.0000") ), get_voter_info( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_TEST_REQUIRE( refund.is_null() ); //200 core tokens should be taken from alice's account BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_balance( "alice1111111" ) ); @@ -713,7 +713,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tes //unstake BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - auto refund = get_refund_request( "alice1111111" ); + auto refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); //auto orig_request_time = refund["request_time"].as_int64(); @@ -725,7 +725,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tes BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); //stake should be taken from alices' balance, and refund request should stay the same BOOST_REQUIRE_EQUAL( core_sym::from_string("400.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); //BOOST_REQUIRE_EQUAL( orig_request_time, refund["request_time"].as_int64() ); @@ -851,7 +851,7 @@ BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_t //bob111111111 increases his stake BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("33.0000"), core_sym::from_string("0.3333") ) ); //alice1111111 stake with transfer to bob111111111 - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); //should increase alice1111111's total_votes prod = get_producer_info( "alice1111111" ); BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("88.8888")) == prod["total_votes"].as_double() ); @@ -1088,7 +1088,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", true ) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //unregister proxy BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() @@ -1106,7 +1106,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "bob111111111" )( "staked", 3000003 ), get_voter_info( "bob111111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(bob111111111) )( "staked", 3000003 ), get_voter_info( "bob111111111" ) ); //unrgister and check that stake is still in place BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() ("proxy", "bob111111111") @@ -1124,7 +1124,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("246.0002"), core_sym::from_string("531.0001") ) ); //check that both proxy flag and stake a correct - REQUIRE_MATCHING_OBJECT( proxy( "carol1111111" )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(carol1111111) )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); //unregister BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() @@ -1146,25 +1146,25 @@ BOOST_FIXTURE_TEST_CASE( proxy_stake_unstake_keeps_proxy_flag, eosio_system_test ) ); issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //stake BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); //stake more BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0000"), core_sym::from_string("20.0000") ) ); //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); //unstake more BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); //unstake the rest BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 0 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 0 ), get_voter_info( "alice1111111" ) ); } FC_LOG_AND_RETHROW() @@ -1173,9 +1173,9 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * cross_15_percent_threshold(); create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); //register as a proxy BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -1188,7 +1188,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), vector(), N(alice1111111) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); //vote for producers BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); @@ -1463,7 +1463,7 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera),N(defproducerb),N(defproducerc) })); auto run_for_1year = [this](int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor) { - + double inflation = double(annual_rate)/double(10000); BOOST_REQUIRE_EQUAL(success(), setinflation( @@ -1485,7 +1485,7 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { } const asset final_supply = get_token_supply(); const int64_t final_savings = get_balance(N(eosio.saving)).get_amount(); - + double computed_new_tokens = double(final_supply.get_amount() - initial_supply.get_amount()); double theoretical_new_tokens = double(initial_supply.get_amount())*inflation; double diff_new_tokens = std::abs(theoretical_new_tokens-computed_new_tokens); @@ -1516,8 +1516,8 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { // 1% inflation for 1 year. 50% savings / 50% bp reward. 10000 / 50000 = 0.2 => 20% blockpay, 80% votepay run_for_1year(100, 20000, 50000); - // 3% inflation for 1 year. 66.6% savings / 33.33% bp reward. 10000/13333 = 0.75 => 75% blockpay, 25% votepay - run_for_1year(300, 30000, 13333); + // 3% inflation for 1 year. 66.6% savings / 33.33% bp reward. 10000/13333 = 0.75 => 75% blockpay, 25% votepay + run_for_1year(300, 30000, 13333); // 0% inflation for 1 year run_for_1year(0, 30000, 50000); @@ -1544,7 +1544,7 @@ BOOST_AUTO_TEST_CASE(extreme_inflation) try { t.produce_block(); asset current_supply; { - vector data = t.get_row_by_account( N(eosio.token), core_symbol.to_symbol_code().value, N(stat), core_symbol.to_symbol_code().value ); + vector data = t.get_row_by_account( N(eosio.token), name(core_symbol.to_symbol_code().value), N(stat), account_name(core_symbol.to_symbol_code().value) ); current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, eosio_system_tester::abi_serializer_max_time)["supply"].template as(); } t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply ); @@ -2541,7 +2541,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) act.name = name; act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); }; // test begins vector prod_perms; @@ -2738,9 +2738,9 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system cross_15_percent_threshold(); create_accounts_with_resources( { N(donald111111), N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); //alice1111111 becomes a producer BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -2748,7 +2748,7 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //alice1111111 makes stake and votes issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); @@ -2763,7 +2763,7 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "donald111111" ), get_voter_info( "donald111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(donald111111) ), get_voter_info( "donald111111" ) ); //bob111111111 chooses alice1111111 as a proxy issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); @@ -2822,10 +2822,10 @@ BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) tr ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //carol1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), regproducer( "carol1111111", 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(carol1111111), 1) ); //bob111111111 chooses alice1111111 as a proxy @@ -2863,13 +2863,13 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("5.0000"), core_sym::from_string("5.0000") ) ); edump((get_voter_info("alice1111111"))); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //bob111111111 stakes and selects alice1111111 as a proxy issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //double regestering should fail without affecting total votes and stake BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), @@ -2878,7 +2878,7 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys ("isproxy", 1) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //uregister BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -2960,9 +2960,9 @@ fc::mutable_variant_object config_to_variant( const eosio::chain::chain_config& BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_tester ) try { create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); //stake more than 15% of total EOS supply to activate chain transfer( "eosio", "alice1111111", core_sym::from_string("600000000.0000"), "eosio" ); @@ -3029,8 +3029,8 @@ BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { create_accounts_with_resources( { N(dan), N(sam) } ); transfer( config::system_account_name, "dan", core_sym::from_string( "10000.0000" ) ); transfer( config::system_account_name, "sam", core_sym::from_string( "10000.0000" ) ); - stake_with_transfer( config::system_account_name, "sam", core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); - stake_with_transfer( config::system_account_name, "dan", core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(sam), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(dan), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); regproducer( config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), vote( N(sam), { config::system_account_name } ) ); @@ -3094,8 +3094,8 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { produce_block(); // stake but but not enough to go live - stake_with_transfer( config::system_account_name, "bob", core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); - stake_with_transfer( config::system_account_name, "carl", core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(bob), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(carl), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob), { N(producer) } ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carl), { N(producer) } ) ); @@ -3151,7 +3151,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { fc::exception, fc_assert_exception_message_is( not_closed_message ) ); // stake enough to go above the 15% threshold - stake_with_transfer( config::system_account_name, "alice", core_sym::from_string( "10000000.0000" ), core_sym::from_string( "10000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(alice), core_sym::from_string( "10000000.0000" ), core_sym::from_string( "10000000.0000" ) ); BOOST_REQUIRE_EQUAL(0, get_producer_info("producer")["unpaid_blocks"].as()); BOOST_REQUIRE_EQUAL( success(), vote( N(alice), { N(producer) } ) ); @@ -3323,7 +3323,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { act.name = name; act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); }; // test begins @@ -3487,7 +3487,7 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( cur_ram_size + 2 * rate, get_global_state()["max_ram_size"].as_uint64() ); BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( "alice1111111", N(setramrate), mvo()("bytes_per_block", rate) ) ); + push_action( N(alice1111111), N(setramrate), mvo()("bytes_per_block", rate) ) ); cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); produce_blocks(10); @@ -3510,14 +3510,14 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol{CORE_SYM}.to_symbol_code() ).empty() ); + BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); //remove row base_tester::push_action( N(eosio.token), N(close), N(alice1111111), mvo() ( "owner", "alice1111111" ) ( "symbol", symbol{CORE_SYM} ) ); - BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol{CORE_SYM}.to_symbol_code() ).empty() ); + BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); auto rlm = control->get_resource_limits_manager(); auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); @@ -5106,7 +5106,8 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { BOOST_AUTO_TEST_CASE( setabi_bios ) try { - validating_tester t( validating_tester::default_config() ); + fc::temp_directory tempdir; + validating_tester t( tempdir, true ); t.execute_setup_policy( setup_policy::preactivate_feature_only ); abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); t.set_code( config::system_account_name, contracts::bios_wasm() ); diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index acca038a6..9a1d82193 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -44,14 +44,14 @@ class eosio_token_tester : public tester { act.name = name; act.data = abi_ser.variant_to_binary( action_type_name, data,abi_serializer_max_time ); - return base_tester::push_action( std::move(act), uint64_t(signer)); + return base_tester::push_action( std::move(act), signer.to_uint64_t() ); } fc::variant get_stats( const string& symbolname ) { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); + vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } @@ -59,7 +59,7 @@ class eosio_token_tester : public tester { { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); + vector data = get_row_by_account( N(eosio.token), acc, N(accounts), account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); } diff --git a/tests/eosio.wrap_tests.cpp b/tests/eosio.wrap_tests.cpp index 4e24a48ff..e7b7cb03e 100644 --- a/tests/eosio.wrap_tests.cpp +++ b/tests/eosio.wrap_tests.cpp @@ -184,7 +184,7 @@ BOOST_FIXTURE_TEST_CASE( wrap_exec_direct, eosio_wrap_tester ) try { ) ); */ wrap_trx.sign( get_private_key( N(alice), "active" ), control->get_chain_id() ); - for( const auto& actor : {"prod1", "prod2", "prod3", "prod4"} ) { + for( const auto& actor : {N(prod1), N(prod2), N(prod3), N(prod4)} ) { wrap_trx.sign( get_private_key( actor, "active" ), control->get_chain_id() ); } push_transaction( wrap_trx ); @@ -194,8 +194,8 @@ BOOST_FIXTURE_TEST_CASE( wrap_exec_direct, eosio_wrap_tester ) try { BOOST_REQUIRE( bool(trace) ); BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio", name{trace->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "reqauth", name{trace->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( config::system_account_name, name{trace->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(reqauth), name{trace->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); } FC_LOG_AND_RETHROW() @@ -238,13 +238,13 @@ BOOST_FIXTURE_TEST_CASE( wrap_with_msig, eosio_wrap_tester ) try { BOOST_REQUIRE_EQUAL( 2, traces.size() ); BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio.wrap", name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio", name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "reqauth", name{traces[1]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); } FC_LOG_AND_RETHROW() @@ -354,13 +354,13 @@ BOOST_FIXTURE_TEST_CASE( wrap_with_msig_producers_change, eosio_wrap_tester ) tr BOOST_REQUIRE_EQUAL( 2, traces.size() ); BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio.wrap", name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio", name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "reqauth", name{traces[1]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); } FC_LOG_AND_RETHROW() From 3717e1d24ca17f99d2062f937bb05266eca3ba75 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 27 Sep 2019 22:27:16 -0400 Subject: [PATCH 38/97] adjust eosio dependency commit --- pipeline.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index c06f57fce..831e35bbd 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,7 +4,7 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "26ed54d90f4e5436faac7fda0f6a0eabbbccc6e2", // eventually update to release/2.0.x + "eosio": "d5c7ee2e52e448abc0f0e854b31b177d427f6bce", // eventually update to release/2.0.x "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } From 298bcf8297769284d888f48ce27979ca76050e36 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 27 Sep 2019 22:31:06 -0400 Subject: [PATCH 39/97] Add support for proposing producer schedules with block signing authorities to eosio.bios and eosio.system contracts. The setprods action of eosio.bios contract has been modified to support block signing authorities in a way that is not backwards compatible. The regproducer action of eosio.system contract is backwards compatible for valid submitted producer keys. A new regproducer2 action has been added to eosio.system contract to support registering a block signing authority to a producer. Both the eosio.bios and eosio.system contract now depend on the set_proposed_producers_ex intrinsic and therefore can only be deployed on an EOSIO chain that has activated the WTMSIG_BLOCK_SIGNATURES protocol feature. --- .../include/eosio.bios/eosio.bios.hpp | 2 +- .../ricardian/eosio.bios.contracts.md.in | 8 +- contracts/eosio.bios/src/eosio.bios.cpp | 2 +- .../include/eosio.system/eosio.system.hpp | 44 +++++-- .../ricardian/eosio.system.clauses.md | 10 +- .../ricardian/eosio.system.contracts.md.in | 24 ++++ contracts/eosio.system/src/voting.cpp | 124 ++++++++++++++---- pipeline.jsonc | 2 +- 8 files changed, 172 insertions(+), 44 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index cadc70e8e..37c387ab6 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -315,7 +315,7 @@ namespace eosiobios { * @param schedule - New list of active producers to set */ [[eosio::action]] - void setprods( std::vector schedule ); + void setprods( const std::vector& schedule ); /** * Set the blockchain parameters diff --git a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in index 1acb02b6b..a08b66e43 100644 --- a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in +++ b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in @@ -154,7 +154,13 @@ icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ {{$action.account}} proposes a block producer schedule of: {{#each schedule}} - 1. {{this.producer_name}} with a block signing key of {{this.block_signing_key}} + 1. {{this.producer_name}} +{{/each}} + +The block signing authorities of each of the producers in the above schedule are listed below: +{{#each schedule}} +### {{this.producer_name}} +{{to_json this.authority}} {{/each}}

unlinkauth

diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index 582f03346..69d6758f3 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -31,7 +31,7 @@ void bios::setalimits( name account, int64_t ram_bytes, int64_t net_weight, int6 set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); } -void bios::setprods( std::vector schedule ) { +void bios::setprods( const std::vector& schedule ) { require_auth( get_self() ); set_proposed_producers( schedule ); } diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index e42f72c87..01f23cced 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1,7 +1,9 @@ #pragma once #include +#include #include +#include #include #include #include @@ -210,19 +212,20 @@ namespace eosiosystem { * Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 */ struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { - name owner; - double total_votes = 0; - eosio::public_key producer_key; /// a packed public key object - bool is_active = true; - std::string url; - uint32_t unpaid_blocks = 0; - time_point last_claim_time; - uint16_t location = 0; + name owner; + double total_votes = 0; + eosio::public_key producer_key; /// a packed public key object + bool is_active = true; + std::string url; + uint32_t unpaid_blocks = 0; + time_point last_claim_time; + uint16_t location = 0; + eosio::binary_extension producer_authority; // added in version 1.9.0 uint64_t primary_key()const { return owner.value; } double by_votes()const { return is_active ? -total_votes : total_votes; } bool active()const { return is_active; } - void deactivate() { producer_key = public_key(); is_active = false; } + void deactivate() { producer_key = public_key(); producer_authority.reset(); is_active = false; } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url) @@ -1083,13 +1086,30 @@ namespace eosiosystem { * @param url - the url of the block producer, normally the url of the block producer presentation website, * @param location - is the country code as defined in the ISO 3166, https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes * - * @pre Producer is not already registered * @pre Producer to register is an account * @pre Authority of producer to register */ [[eosio::action]] void regproducer( const name& producer, const public_key& producer_key, const std::string& url, uint16_t location ); + /** + * Register producer action. + * + * @details Register producer action, indicates that a particular account wishes to become a producer, + * this action will create a `producer_config` and a `producer_info` object for `producer` scope + * in producers tables. + * + * @param producer - account registering to be a producer candidate, + * @param producer_authority - the weighted threshold multisig block signing authority of the block producer used to sign blocks, + * @param url - the url of the block producer, normally the url of the block producer presentation website, + * @param location - is the country code as defined in the ISO 3166, https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes + * + * @pre Producer to register is an account + * @pre Authority of producer to register + */ + [[eosio::action]] + void regproducer2( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ); + /** * Unregister producer action. * @@ -1316,6 +1336,7 @@ namespace eosiosystem { using sellram_action = eosio::action_wrapper<"sellram"_n, &system_contract::sellram>; using refund_action = eosio::action_wrapper<"refund"_n, &system_contract::refund>; using regproducer_action = eosio::action_wrapper<"regproducer"_n, &system_contract::regproducer>; + using regproducer2_action = eosio::action_wrapper<"regproducer2"_n, &system_contract::regproducer2>; using unregprod_action = eosio::action_wrapper<"unregprod"_n, &system_contract::unregprod>; using setram_action = eosio::action_wrapper<"setram"_n, &system_contract::setram>; using setramrate_action = eosio::action_wrapper<"setramrate"_n, &system_contract::setramrate>; @@ -1386,7 +1407,8 @@ namespace eosiosystem { const asset& stake_net_quantity, const asset& stake_cpu_quantity, bool transfer ); void update_voting_power( const name& voter, const asset& total_update ); - // defined in voting.hpp + // defined in voting.cpp + void register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ); void update_elected_producers( const block_timestamp& timestamp ); void update_votes( const name& voter, const name& proxy, const std::vector& producers, bool voting ); void propagate_weight_change( const voter_info& voter ); diff --git a/contracts/eosio.system/ricardian/eosio.system.clauses.md b/contracts/eosio.system/ricardian/eosio.system.clauses.md index 19be74f81..ef5bfc987 100644 --- a/contracts/eosio.system/ricardian/eosio.system.clauses.md +++ b/contracts/eosio.system/ricardian/eosio.system.clauses.md @@ -6,13 +6,13 @@ User agreement for the chain can go here. I, {{producer}}, hereby nominate myself for consideration as an elected block producer. -If {{producer}} is selected to produce blocks by the system contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. +If {{producer}} is selected to produce blocks by the system contract, I will sign blocks with my registered block signing keys and I hereby attest that I will keep these keys secret and secure. -If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. +If {{producer}} is unable to perform obligations under this contract I will resign my position using the unregprod action. I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. -{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: +{{producer}} hereby agrees to only use my registered block signing keys to sign messages under the following scenarios: * proposing an objectively valid block at the time appointed by the block scheduling algorithm; * pre-confirming a block produced by another producer in the schedule when I find said block objectively valid; @@ -20,8 +20,8 @@ I acknowledge that a block is 'objectively valid' if it conforms to the determin I hereby accept liability for any and all provable damages that result from my: -* signing two different block proposals with the same timestamp with {{producer_key}}; -* signing two different block proposals with the same block number with {{producer_key}}; +* signing two different block proposals with the same timestamp; +* signing two different block proposals with the same block number; * signing any block proposal which builds off of an objectively invalid block; * signing a pre-confirmation for an objectively invalid block; * or, signing a confirmation for a block for which I do not possess pre-confirmation messages from more than two-thirds of the active block producers. diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 70e1b7cd4..296094e4c 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -309,6 +309,30 @@ icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ Register {{producer}} account as a block producer candidate. +URL: {{url}} +Location code: {{location}} +Block signing key: {{producer_key}} + +## Block Producer Agreement +{{$clauses.BlockProducerAgreement}} + +

regproducer2

+ +--- +spec_version: "0.2.0" +title: Register as a Block Producer Candidate +summary: 'Register {{nowrap producer}} account as a block producer candidate' +icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ +--- + +Register {{producer}} account as a block producer candidate. + +URL: {{url}} +Location code: {{location}} +Block signing authority: +{{to_json producer_authority}} + +## Block Producer Agreement {{$clauses.BlockProducerAgreement}}

regproxy

diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 95f1dd36a..a7ac599fd 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -9,6 +10,9 @@ #include #include +#include +#include +#include #include #include @@ -20,20 +24,40 @@ namespace eosiosystem { using eosio::microseconds; using eosio::singleton; - void system_contract::regproducer( const name& producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { - check( url.size() < 512, "url too long" ); - check( producer_key != eosio::public_key(), "public key should not be the default value" ); - require_auth( producer ); + eosio::block_signing_authority convert_to_block_signing_authority( const eosio::public_key& producer_key ) { + return eosio::block_signing_authority_v0{ .threshold = 1, .keys = {{producer_key, 1}} }; + } + template struct overloaded : Ts... { using Ts::operator()...; }; + template overloaded(Ts...) -> overloaded; + + bool is_null_key( const eosio::public_key& pub_key ) { + return std::visit( overloaded{ + []( const eosio::ecc_public_key& k ) { return (k == eosio::ecc_public_key{}); }, + []( const eosio::webauthn_public_key& k ) { return (k.key == eosio::ecc_public_key{}); } + }, pub_key ); + } + + void system_contract::register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { auto prod = _producers.find( producer.value ); const auto ct = current_time_point(); + eosio::public_key producer_key{}; + + std::visit( [&](auto&& auth ) { + if( auth.keys.size() == 1 ) { + // if the producer_authority consists of a single key, use that key in the legacy producer_key field + producer_key = auth.keys[0].key; + } + }, producer_authority ); + if ( prod != _producers.end() ) { _producers.modify( prod, producer, [&]( producer_info& info ){ - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; + info.producer_key = producer_key; + info.is_active = true; + info.url = url; + info.location = location; + info.producer_authority.emplace( producer_authority ); if ( info.last_claim_time == time_point() ) info.last_claim_time = ct; }); @@ -49,13 +73,14 @@ namespace eosiosystem { } } else { _producers.emplace( producer, [&]( producer_info& info ){ - info.owner = producer; - info.total_votes = 0; - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; - info.last_claim_time = ct; + info.owner = producer; + info.total_votes = 0; + info.producer_key = producer_key; + info.is_active = true; + info.url = url; + info.location = location; + info.last_claim_time = ct; + info.producer_authority.emplace( producer_authority ); }); _producers2.emplace( producer, [&]( producer_info2& info ){ info.owner = producer; @@ -65,6 +90,47 @@ namespace eosiosystem { } + void system_contract::regproducer( const name& producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { + require_auth( producer ); + check( url.size() < 512, "url too long" ); + + check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); + check( !is_null_key( producer_key ), "public key should not be the default value" ); + check_permission_authorization( null_account, active_permission, {} ); // aborts transaction if native side cannot unpack producer_key + + register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); + } + + void system_contract::regproducer2( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { + require_auth( producer ); + check( url.size() < 512, "url too long" ); + + std::visit( [&](auto&& auth ) { + uint32_t sum_weights = 0; + std::set unique_keys; + + for (const auto& kw: auth.keys ) { + check( kw.key.index() < 2, "currently only K1 and R1 producer keys are supported" ); + check( !is_null_key( kw.key ), "producer authority includes an invalid key" ); + + if( std::numeric_limits::max() - sum_weights <= kw.weight ) { + sum_weights = std::numeric_limits::max(); + } else { + sum_weights += kw.weight; + } + + unique_keys.insert(kw.key); + } + + check( auth.keys.size() == unique_keys.size(), "producer authority includes a duplicated key" ); + check( auth.threshold > 0, "producer authority has a threshold of 0" ); + check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); + }, producer_authority ); + + + register_producer( producer, producer_authority, url, location ); + } + void system_contract::unregprod( const name& producer ) { require_auth( producer ); @@ -79,25 +145,35 @@ namespace eosiosystem { auto idx = _producers.get_index<"prototalvote"_n>(); - std::vector< std::pair > top_producers; + using value_type = std::pair; + std::vector< value_type > top_producers; top_producers.reserve(21); - for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) { - top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location}) ); + for( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) { + top_producers.emplace_back( + eosio::producer_authority{ + .producer_name = it->owner, + .authority = it->producer_authority.has_value() ? *it->producer_authority + : convert_to_block_signing_authority( it->producer_key ) + }, + it->location + ); } - if ( top_producers.size() == 0 || top_producers.size() < _gstate.last_producer_schedule_size ) { + if( top_producers.size() == 0 || top_producers.size() < _gstate.last_producer_schedule_size ) { return; } - /// sort by producer name - std::sort( top_producers.begin(), top_producers.end() ); + std::sort( top_producers.begin(), top_producers.end(), []( const value_type& lhs, const value_type& rhs ) { + return lhs.first.producer_name < rhs.first.producer_name; // sort by producer name + // return lhs.second < rhs.second; // sort by location + } ); - std::vector producers; + std::vector producers; producers.reserve(top_producers.size()); - for( const auto& item : top_producers ) - producers.push_back(item.first); + for( auto& item : top_producers ) + producers.push_back( std::move(item.first) ); if( set_proposed_producers( producers ) >= 0 ) { _gstate.last_producer_schedule_size = static_cast( top_producers.size() ); diff --git a/pipeline.jsonc b/pipeline.jsonc index 831e35bbd..7acda92e4 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,7 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "d5c7ee2e52e448abc0f0e854b31b177d427f6bce", // eventually update to release/2.0.x - "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x + "eosio.cdt": "72cbc2b6cb045d744d241d53a78467d5b65b9191" // eventually update to release/1.7.x } } } From cf9dafcb666b19c10210b2644170e30e4f8f7739 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 30 Sep 2019 19:08:25 -0400 Subject: [PATCH 40/97] verify keys provided when registering producers can be successfully unpacked --- contracts/eosio.system/src/voting.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index a7ac599fd..6f418a887 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -96,7 +96,7 @@ namespace eosiosystem { check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); check( !is_null_key( producer_key ), "public key should not be the default value" ); - check_permission_authorization( null_account, active_permission, {} ); // aborts transaction if native side cannot unpack producer_key + check_permission_authorization( null_account, active_permission, {producer_key} ); // aborts transaction if native side cannot unpack producer_key register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); } @@ -105,9 +105,9 @@ namespace eosiosystem { require_auth( producer ); check( url.size() < 512, "url too long" ); + std::set unique_keys; std::visit( [&](auto&& auth ) { uint32_t sum_weights = 0; - std::set unique_keys; for (const auto& kw: auth.keys ) { check( kw.key.index() < 2, "currently only K1 and R1 producer keys are supported" ); @@ -127,6 +127,7 @@ namespace eosiosystem { check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); }, producer_authority ); + check_permission_authorization( null_account, active_permission, unique_keys ); // aborts transaction if native side cannot unpack all of the keys register_producer( producer, producer_authority, url, location ); } From fc31fe3b05b805fae3e539c3f3f04693d50046eb Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 30 Sep 2019 19:08:54 -0400 Subject: [PATCH 41/97] forgot to reflect producer_authority field --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 01f23cced..89d05a676 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -229,7 +229,7 @@ namespace eosiosystem { // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url) - (unpaid_blocks)(last_claim_time)(location) ) + (unpaid_blocks)(last_claim_time)(location)(producer_authority) ) }; /** From 261fd02d47c7c00b408d506afad42593b343b4b9 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 30 Sep 2019 19:11:56 -0400 Subject: [PATCH 42/97] add eosio_system_tests/producer_wtmsig test --- tests/eosio.system_tests.cpp | 83 ++++++++++++++++++++++++++++++++++++ tests/main.cpp | 7 ++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index ce51882f1..b8cf7e1ed 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -803,6 +803,89 @@ BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { + cross_15_percent_threshold(); + + BOOST_REQUIRE_EQUAL( control->active_producers().version, 0u ); + + issue_and_transfer( N(alice1111111), core_sym::from_string("200000000.0000"), config::system_account_name ); + block_signing_authority_v0 alice_signing_authority; + alice_signing_authority.threshold = 1; + alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs1"), .weight = 1} ); + alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs2"), .weight = 1} ); + producer_authority alice_producer_authority = {.producer_name = N(alice1111111), .authority = alice_signing_authority}; + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); + + block_signing_private_keys.emplace(get_public_key(N(alice1111111), "bs1"), get_private_key(N(alice1111111), "bs1")); + + auto alice_prod_info = get_producer_info( N(alice1111111) ); + wdump((alice_prod_info)); + BOOST_REQUIRE_EQUAL( alice_prod_info["is_active"], true ); + + produce_block(); + produce_block( fc::minutes(2) ); + produce_blocks(2); + BOOST_REQUIRE_EQUAL( control->active_producers().version, 1u ); + produce_block(); + BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); + produce_block(); + + alice_signing_authority.threshold = 0; + alice_producer_authority.authority = alice_signing_authority; + + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority has a threshold of 0"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + + alice_signing_authority.threshold = 3; + alice_producer_authority.authority = alice_signing_authority; + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority is unsatisfiable"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + + alice_signing_authority.threshold = 1; + alice_signing_authority.keys[1] = alice_signing_authority.keys[0]; + alice_producer_authority.authority = alice_signing_authority; + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes a duplicated key"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + + alice_signing_authority.keys[1] = {}; + alice_producer_authority.authority = alice_signing_authority; + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes an invalid key"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { cross_15_percent_threshold(); diff --git a/tests/main.cpp b/tests/main.cpp index 2c658f31a..e3d617509 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -31,7 +31,12 @@ boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { break; } } - if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + + if(is_verbose) { + fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug); + } else { + fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + } // Register fc::exception translator boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); From 5ac7138463ddffa2c250cfc5f73a62d5aa5a0055 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 1 Oct 2019 11:43:11 -0400 Subject: [PATCH 43/97] remove unnecessary checks --- contracts/eosio.system/src/voting.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 6f418a887..0b385372d 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -96,7 +96,6 @@ namespace eosiosystem { check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); check( !is_null_key( producer_key ), "public key should not be the default value" ); - check_permission_authorization( null_account, active_permission, {producer_key} ); // aborts transaction if native side cannot unpack producer_key register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); } @@ -127,8 +126,6 @@ namespace eosiosystem { check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); }, producer_authority ); - check_permission_authorization( null_account, active_permission, unique_keys ); // aborts transaction if native side cannot unpack all of the keys - register_producer( producer, producer_authority, url, location ); } From 1f46094943bfbc58c7cba2d9b132fe0c03a2db80 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 1 Oct 2019 22:10:54 -0400 Subject: [PATCH 44/97] adjust eosio dependency commit again --- pipeline.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 831e35bbd..f9bafb1ea 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,7 +4,7 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "d5c7ee2e52e448abc0f0e854b31b177d427f6bce", // eventually update to release/2.0.x + "eosio": "89166b5a314fa2bcda664329efcc13f505bd8eac", // eventually update to release/2.0.x "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } From 4b608fe7c66c3460c0401561f8fe4432bc77a7ec Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 Oct 2019 09:36:23 -0400 Subject: [PATCH 45/97] output on unit test failure --- .cicd/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/test.sh b/.cicd/test.sh index 521530199..43083b6fc 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -11,6 +11,6 @@ fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" -TEST_COMMANDS="ctest -j $JOBS" +TEST_COMMANDS="ctest -j $JOBS --output-on-failure" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" -eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" From 86f5bf54fa8b0c1bac56ad489a5accc9e9e7219e Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 Oct 2019 09:47:16 -0400 Subject: [PATCH 46/97] fix eosio_system_tests/setabi_bios test --- tests/eosio.system_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b8cf7e1ed..d59dd4d47 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5191,7 +5191,8 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { BOOST_AUTO_TEST_CASE( setabi_bios ) try { fc::temp_directory tempdir; validating_tester t( tempdir, true ); - t.execute_setup_policy( setup_policy::preactivate_feature_only ); + t.execute_setup_policy( setup_policy::full ); + abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); t.set_code( config::system_account_name, contracts::bios_wasm() ); t.set_abi( config::system_account_name, contracts::bios_abi().data() ); From 79b1e07c209e9023e9e635de16d184f86ed51c4d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 Oct 2019 17:51:57 -0400 Subject: [PATCH 47/97] Update `regproducer` and `regproducer2` in eosio.system contract to relax validation rules on keys. Also use the new CDT `is_valid` member function of `block_signing_authority_v0` to validate the user-submitted block signing authorities (requires bumping dependency on CDT). Changes to tests to reflect the fact that `set_proposed_producers_ex` now accepts authorities even with invalid keys (requires bumping dependency on EOSIO). --- contracts/eosio.system/src/voting.cpp | 33 +-------------------------- pipeline.jsonc | 4 ++-- tests/eosio.system_tests.cpp | 20 ++++++++++++---- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 0b385372d..d26e187c6 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -28,16 +28,6 @@ namespace eosiosystem { return eosio::block_signing_authority_v0{ .threshold = 1, .keys = {{producer_key, 1}} }; } - template struct overloaded : Ts... { using Ts::operator()...; }; - template overloaded(Ts...) -> overloaded; - - bool is_null_key( const eosio::public_key& pub_key ) { - return std::visit( overloaded{ - []( const eosio::ecc_public_key& k ) { return (k == eosio::ecc_public_key{}); }, - []( const eosio::webauthn_public_key& k ) { return (k.key == eosio::ecc_public_key{}); } - }, pub_key ); - } - void system_contract::register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { auto prod = _producers.find( producer.value ); const auto ct = current_time_point(); @@ -94,9 +84,6 @@ namespace eosiosystem { require_auth( producer ); check( url.size() < 512, "url too long" ); - check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); - check( !is_null_key( producer_key ), "public key should not be the default value" ); - register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); } @@ -104,26 +91,8 @@ namespace eosiosystem { require_auth( producer ); check( url.size() < 512, "url too long" ); - std::set unique_keys; std::visit( [&](auto&& auth ) { - uint32_t sum_weights = 0; - - for (const auto& kw: auth.keys ) { - check( kw.key.index() < 2, "currently only K1 and R1 producer keys are supported" ); - check( !is_null_key( kw.key ), "producer authority includes an invalid key" ); - - if( std::numeric_limits::max() - sum_weights <= kw.weight ) { - sum_weights = std::numeric_limits::max(); - } else { - sum_weights += kw.weight; - } - - unique_keys.insert(kw.key); - } - - check( auth.keys.size() == unique_keys.size(), "producer authority includes a duplicated key" ); - check( auth.threshold > 0, "producer authority has a threshold of 0" ); - check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); + check( auth.is_valid(), "invalid producer authority" ); }, producer_authority ); register_producer( producer, producer_authority, url, location ); diff --git a/pipeline.jsonc b/pipeline.jsonc index bf1d2d233..95bd0cd13 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,8 +4,8 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "89166b5a314fa2bcda664329efcc13f505bd8eac", // eventually update to release/2.0.x - "eosio.cdt": "72cbc2b6cb045d744d241d53a78467d5b65b9191" // eventually update to release/1.7.x + "eosio": "329071ae8ae7c8e467f42079ebdb09e675d7e702", // eventually update to release/2.0.x + "eosio.cdt": "aad0c4729b848c9cbe409aa1fdd917797a4d91e7" // eventually update to release/1.7.x } } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d59dd4d47..c78439a1d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -841,7 +841,8 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { alice_signing_authority.threshold = 0; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority has a threshold of 0"), + // Ensure an authority with a threshold of 0 is rejected. + BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -850,9 +851,10 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + // Ensure an authority that is not satisfiable is rejected. alice_signing_authority.threshold = 3; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority is unsatisfiable"), + BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -861,10 +863,11 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + // Ensure an authority with duplicate keys is rejected. alice_signing_authority.threshold = 1; alice_signing_authority.keys[1] = alice_signing_authority.keys[0]; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes a duplicated key"), + BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -873,9 +876,10 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + // However, an authority with an invalid key is okay. alice_signing_authority.keys[1] = {}; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes an invalid key"), + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -884,6 +888,14 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + produce_block(); + produce_block( fc::minutes(2) ); + produce_blocks(2); + BOOST_REQUIRE_EQUAL( control->active_producers().version, 2u ); + produce_block(); + BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); + produce_block(); + } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { From fdd1653fa8045e42bc52d4a0c469b4bf3bdc7884 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 7 Oct 2019 12:37:02 -0400 Subject: [PATCH 48/97] bump version to v1.9.0-rc1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52663847d..0df69f59a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.8.0-rc1 +## Version : 1.9.0-rc1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. From 6c4a6c28bf80dffb56218c1410d528779e20d426 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 7 Oct 2019 13:43:21 -0400 Subject: [PATCH 49/97] update pipeline.jsonc --- pipeline.jsonc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 95bd0cd13..b9d36799a 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,8 +4,8 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "329071ae8ae7c8e467f42079ebdb09e675d7e702", // eventually update to release/2.0.x - "eosio.cdt": "aad0c4729b848c9cbe409aa1fdd917797a4d91e7" // eventually update to release/1.7.x + "eosio": "release/2.0.x", + "eosio.cdt": "release/1.7.x" } } } From ca5afe93dfcd34f804c4fbbda5be308db09bd190 Mon Sep 17 00:00:00 2001 From: ovi Date: Fri, 18 Oct 2019 17:21:25 +0800 Subject: [PATCH 50/97] Update the README.md build section --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index c610475dd..81bed8345 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,7 @@ Dependencies: * [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.0-rc2) * [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.1) -To build the contracts and the unit tests: -* First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. -* Second, make sure that you have ```sudo make install```ed __eosio__. -* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. +To build the contracts follow the instructions in [`Compile and deploy` section](./docs/02_compile-and-deploy.md). After build: * The unit tests executable is placed in the _build/tests_ and is named __unit_test__. From 15ba163b88fa592db3ee261ff8a59281cbdb1519 Mon Sep 17 00:00:00 2001 From: ovi Date: Fri, 18 Oct 2019 18:46:54 +0800 Subject: [PATCH 51/97] clean up README.md, the referenced build section has the after build status. --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index f32e96201..04e491a69 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,6 @@ Dependencies: To build the contracts follow the instructions in [`Compile and deploy` section](./docs/02_compile-and-deploy.md). -After build: -* If the build was configured to also build unit tests, the unit tests executable is placed in the _build/tests_ folder and is named __unit_test__. -* The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. -* Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. - ## Contributing [Contributing Guide](./CONTRIBUTING.md) From 222907aaf6b5e76898c8f3b0b816a83f45968c90 Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 19 Oct 2019 10:28:20 -0400 Subject: [PATCH 52/97] change pronoun in buyrex Ricardian summary --- contracts/eosio.system/ricardian/eosio.system.contracts.md.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 296094e4c..9ab33cd88 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -75,7 +75,7 @@ icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ --- spec_version: "0.2.0" title: Buy REX Tokens -summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and his vote stake increases by {{nowrap amount}}' +summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}' icon: @ICON_BASE_URL@/@REX_ICON_URI@ --- From c5185789683fb6d440231c32d61caa53eceb3507 Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 19 Oct 2019 10:28:20 -0400 Subject: [PATCH 53/97] change pronoun in buyrex Ricardian summary --- contracts/eosio.system/ricardian/eosio.system.contracts.md.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 296094e4c..9ab33cd88 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -75,7 +75,7 @@ icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ --- spec_version: "0.2.0" title: Buy REX Tokens -summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and his vote stake increases by {{nowrap amount}}' +summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}' icon: @ICON_BASE_URL@/@REX_ICON_URI@ --- From cf5db63e7fb2a769582c314678329ee432c5a83e Mon Sep 17 00:00:00 2001 From: ovi Date: Tue, 22 Oct 2019 22:09:44 +0300 Subject: [PATCH 54/97] update the token issue guide since now the token can be issued only to the account creator --- ...ow-to-create-issue-and-transfer-a-token.md | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md index 584e4a648..3693d37e6 100644 --- a/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -14,7 +14,7 @@ git clone https://github.com/EOSIO/eosio.contracts --branch master --single-bran ``` ```text -cd eosio.contracts/eosio.token +cd eosio.contracts/contracts/eosio.token ``` ## Step 2: Create Account for Contract @@ -34,7 +34,7 @@ eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen ## Step 4: Deploy the Token Contract ```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/contracts/eosio.token --abi eosio.token.abi -p eosio.token@active ``` Result should look similar to the one below: @@ -74,38 +74,34 @@ This command created a new token `SYS` with a precision of 4 decimals and a maxi ## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. +The issuer can issue new tokens to the issuer account in our case `eosio`. ```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +cleos push action eosio.token issue '[ "eosio", "100.0000 SYS", "memo" ]' -p eosio@active ``` Result should look similar to the one below: ```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +executed transaction: a26b29d66044ad95edf0fc04bad3073e99718bc26d27f3c006589adedb717936 128 bytes 337 us +# eosio.token <= eosio.token::issue {"to":"eosio","quantity":"100.0000 SYS","memo":"memo"} +warning: transaction executed locally, but may not be confirmed by the network yet ] ``` ## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. +Now that account `eosio` has been issued tokens, transfer some of them to account `bob`. ```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +cleos push action eosio.token transfer '[ "eosio", "bob", "25.0000 SYS", "m" ]' -p eosio@active ``` Result should look similar to the one below: ```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +executed transaction: 60d334850151cb95c35fe31ce2e8b536b51441c5fd4c3f2fea98edcc6d69f39d 128 bytes 497 us +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} +# eosio <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} +# bob <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} +warning: transaction executed locally, but may not be confirmed by the network yet ] ``` Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) @@ -118,10 +114,10 @@ Result: 25.00 SYS ``` -Check "alice's" balance, notice that tokens were deducted from the account +Check "eosio's" balance, notice that tokens were deducted from the account ```shell -cleos get currency balance eosio.token alice SYS +cleos get currency balance eosio.token eosio SYS ``` Result: From 2f710850064dfcddd9ecd4b1cede21b7f23cb80f Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 23 Oct 2019 22:06:51 +0300 Subject: [PATCH 55/97] correct problems introduced after merging with develop branch and resolving conflicts --- .../include/eosio.bios/eosio.bios.hpp | 31 ------------------- .../include/eosio.system/exchange_state.hpp | 3 +- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index c036eecbb..37c387ab6 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -7,37 +7,6 @@ #include #include -// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` -#include - -namespace eosio { - namespace internal_use_do_not_use { - extern "C" { - __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); - - __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); - } - } -} - -namespace eosio { - bool is_feature_activated( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); - } - - void preactivate_feature( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); - } -} - /** * EOSIO Contracts * diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 64a238227..03782cb12 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -59,4 +59,5 @@ namespace eosiosystem { }; typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; -} + /** @}*/ // enf of @addtogroup eosiosystem +} /// namespace eosiosystem \ No newline at end of file From fdddaff6b1f40b6564d1000941a3f318c6e9207e Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 24 Oct 2019 14:14:12 +0300 Subject: [PATCH 56/97] update the compile/build steps to include compilation of the tests as well if wanted by the user --- docs/02_compile-and-deploy.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/02_compile-and-deploy.md b/docs/02_compile-and-deploy.md index b7502b3f9..06fbd8610 100644 --- a/docs/02_compile-and-deploy.md +++ b/docs/02_compile-and-deploy.md @@ -1,12 +1,23 @@ ## How to compile the eosio.contracts ### Preconditions -`eosio.cdt` should be installed already, if you do not have it already follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases). To verify if you have `eosio.cdt` installed and its version run the following command +Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases) to install it. To verify if you have `eosio.cdt` installed and its version run the following command ```sh eosio-cpp -v ``` +#### Build contracts using the build script + +##### To build contracts alone +Run the `build.sh` script in the top directory to build all the contracts. + +##### To build the contracts and unit tests +1. Ensure an appropriate version of `eosio` has been built from source and installed. Installing `eosio` from binaries `is not` sufficient. You can find instructions on how to do it [here](https://github.com/EOSIO/eos/blob/master/README.md) in section `Building from Sources`. +2. Run the `build.sh` script in the top directory with the `-t` flag to build all the contracts and the unit tests for these contracts. + +#### Build contracts manually + To compile the `eosio.contracts` execute the following commands. On all platforms except macOS: @@ -20,7 +31,7 @@ make -j$( nproc ) cd .. ``` -For macOS +For macOS: ```sh cd you_local_path_to/eosio.contracts/ rm -fr build From 66945740dcf7fe5777c5acd4a1a2b005b8434267 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 24 Oct 2019 14:44:44 -0400 Subject: [PATCH 57/97] Fix for broken test metrics. --- .cicd/test.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.cicd/test.sh b/.cicd/test.sh index 43083b6fc..d4e45617e 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -11,6 +11,24 @@ fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" -TEST_COMMANDS="ctest -j $JOBS --output-on-failure" +TEST_COMMANDS="ctest -j $JOBS --output-on-failure -T Test" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" +set +e eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" +EXIT_STATUS=$? +# buildkite +if [[ "$BUILDKITE" == 'true' ]]; then + cd build + # upload artifacts + echo '+++ :arrow_up: Uploading Artifacts' + echo 'Exporting xUnit XML' + mv -f ./tests/Testing/$(ls ./tests/Testing/ | grep '2' | tail -n 1)/Test.xml test-results.xml + echo 'Uploading artifacts' + buildkite-agent artifact upload test-results.xml + echo 'Done uploading artifacts.' +fi +# re-throw +if [[ "$EXIT_STATUS" != 0 ]]; then + echo "Failing due to non-zero exit status from ctest: $EXIT_STATUS" + exit $EXIT_STATUS +fi \ No newline at end of file From adbbc6640465dc8845da2b00c9705ddc857f6397 Mon Sep 17 00:00:00 2001 From: dskvr Date: Tue, 29 Oct 2019 12:46:20 -0400 Subject: [PATCH 58/97] Remove documentation from private functions --- .../include/eosio.token/eosio.token.hpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index 08d146092..d5e20164a 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -96,12 +96,6 @@ namespace eosio { [[eosio::action]] void close( const name& owner, const symbol& symbol ); - /** - * Gets the supply for token `sym_code`, created by `token_contract_account` account. - * - * @param token_contract_account - the account to get the supply for, - * @param sym_code - the symbol to get the supply for. - */ static asset get_supply( const name& token_contract_account, const symbol_code& sym_code ) { stats statstable( token_contract_account, sym_code.raw() ); @@ -109,14 +103,6 @@ namespace eosio { return st.supply; } - /** - * Get the balance for a token `sym_code` created by `token_contract_account` account, - * for account `owner`. - * - * @param token_contract_account - the token creator account, - * @param owner - the account for which the token balance is returned, - * @param sym_code - the token for which the balance is returned. - */ static asset get_balance( const name& token_contract_account, const name& owner, const symbol_code& sym_code ) { accounts accountstable( token_contract_account, owner.value ); From b816cc453dd2a418669ca75cd8dcad151116b17a Mon Sep 17 00:00:00 2001 From: dskvr Date: Tue, 29 Oct 2019 12:47:11 -0400 Subject: [PATCH 59/97] remove documentation from private method --- .../include/eosio.system/exchange_state.hpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 03782cb12..e07153566 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -38,16 +38,7 @@ namespace eosiosystem { asset convert_from_exchange( connector& reserve, const asset& tokens ); asset convert( const asset& from, const symbol& to ); asset direct_convert( const asset& from, const symbol& to ); - /** - * Given two connector balances (inp_reserve and out_reserve), and an incoming amount - * of inp, this function calculates the delta out using Banacor equation. - * - * @param inp - input amount, same units as inp_reserve - * @param inp_reserve - the input connector balance - * @param out_reserve - the output connector balance - * - * @return int64_t - conversion output amount - */ + static int64_t get_bancor_output( int64_t inp_reserve, int64_t out_reserve, int64_t inp ); @@ -60,4 +51,4 @@ namespace eosiosystem { typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; /** @}*/ // enf of @addtogroup eosiosystem -} /// namespace eosiosystem \ No newline at end of file +} /// namespace eosiosystem From 418c654c5522059fefc3499cf6dcd04da867720a Mon Sep 17 00:00:00 2001 From: dskvr Date: Tue, 29 Oct 2019 12:50:43 -0400 Subject: [PATCH 60/97] Remove private methods and struct documentation for first iteration, only need action reference --- .../include/eosio.bios/eosio.bios.hpp | 68 +------------------ 1 file changed, 1 insertion(+), 67 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 37c387ab6..76a2215e9 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -36,14 +36,6 @@ namespace eosiobios { using eosio::permission_level; using eosio::public_key; - /** - * A weighted permission. - * - * @details Defines a weighted permission, that is a permission which has a weight associated. - * A permission is defined by an account name plus a permission name. The weight is going to be - * used against a threshold, if the weight is equal or greater than the threshold set then authorization - * will pass. - */ struct permission_level_weight { permission_level permission; uint16_t weight; @@ -52,11 +44,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) }; - /** - * Weighted key. - * - * @details A weighted key is defined by a public key and an associated weight. - */ struct key_weight { eosio::public_key key; uint16_t weight; @@ -65,11 +52,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( key_weight, (key)(weight) ) }; - /** - * Wait weight. - * - * @details A wait weight is defined by a number of seconds to wait for and a weight. - */ struct wait_weight { uint32_t wait_sec; uint16_t weight; @@ -78,15 +60,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) }; - /** - * Blockchain authority. - * - * @details An authority is defined by: - * - a vector of key_weights (a key_weight is a public key plus a weight), - * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) - * - a vector of wait_weights (a wait_weight is defined by a number of seconds to wait and a weight) - * - a threshold value - */ struct authority { uint32_t threshold = 0; std::vector keys; @@ -97,19 +70,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) }; - /** - * Blockchain block header. - * - * @details A block header is defined by: - * - a timestamp, - * - the producer that created it, - * - a confirmed flag default as zero, - * - a link to previous block, - * - a link to the transaction merkel root, - * - a link to action root, - * - a schedule version, - * - and a producers' schedule. - */ struct block_header { uint32_t timestamp; name producer; @@ -125,26 +85,9 @@ namespace eosiobios { (schedule_version)(new_producers)) }; - /** - * @defgroup eosiobios eosio.bios - * @ingroup eosiocontracts - * - * eosio.bios is a minimalistic system contract that only supplies the actions that are absolutely - * critical to bootstrap a chain and nothing more. - * - * @{ - */ class [[eosio::contract("eosio.bios")]] bios : public eosio::contract { public: using contract::contract; - /** - * @{ - * These actions map one-on-one with the ones defined in - * [Native Action Handlers](@ref native_action_handlers) section. - * They are present here so they can show up in the abi file and thus user can send them - * to this contract, but they have no specific implementation at this contract level, - * they will execute the implementation at the core level and nothing else. - */ /** * New account action * @@ -358,11 +301,6 @@ namespace eosiobios { [[eosio::action]] void reqactivated( const eosio::checksum256& feature_digest ); - /** - * Abi hash structure - * - * @details Abi hash structure is defined by contract owner and the contract hash. - */ struct [[eosio::table]] abi_hash { name owner; checksum256 hash; @@ -371,9 +309,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; - /** - * Multi index table that stores the contracts' abi index by their owners/accounts. - */ typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; using newaccount_action = action_wrapper<"newaccount"_n, &bios::newaccount>; @@ -392,5 +327,4 @@ namespace eosiobios { using activate_action = action_wrapper<"activate"_n, &bios::activate>; using reqactivated_action = action_wrapper<"reqactivated"_n, &bios::reqactivated>; }; - /** @}*/ // end of @defgroup eosiobios eosio.bios -} /// namespace eosiobios +} From 241022403e8319052b3b2280702b7d6ef4e85902 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 31 Oct 2019 16:45:43 +0200 Subject: [PATCH 61/97] Re-do the three tutorials to not have reference to cleos documentation cause it is not deployed yet --- docs/03_guides/02_how-to-buy-ram.md | 25 +++++++++++++++++----- docs/03_guides/03_how-to-stake.md | 30 ++++++++++++++++++++++----- docs/03_guides/04_how-to-vote.md | 32 ++++++++++++++++++++++++----- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/docs/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md index 878757e35..2885c5143 100644 --- a/docs/03_guides/02_how-to-buy-ram.md +++ b/docs/03_guides/02_how-to-buy-ram.md @@ -1,8 +1,23 @@ -## How buy RAM +## Goal -You can buy RAM using `cleos` command line tool or using a wallet that implements the buy RAM functionality. +Setup an account that require multiple signatures for signing a transaction -TO DO: verify and correct the next url -To buy ram using `cleos` check [how to buy ram](https://eosio.github.io/eos/cleos/how-to-buy-ram) +## Before you begin -To buy ram using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file +* You have an account + +* Ensure the reference system contracts from `eosio.contracts` repository is deployed and used to manage system resources + +* You have sufficient token allocated to your account + +* Install the currently supported version of cleos + +* Unlock your wallet + +## Steps + +Buys RAM in value of 0.1 SYS tokens for account `alice`: + +```shell +cleos system buyram alice alice "0.1 SYS" -p alice@active +``` \ No newline at end of file diff --git a/docs/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md index bf2a1f381..83f3a8da7 100644 --- a/docs/03_guides/03_how-to-stake.md +++ b/docs/03_guides/03_how-to-stake.md @@ -1,8 +1,28 @@ -## How to stake tokens for CPU and/or NET bandwidth +## Goal -You can stake tokens for CPU and/or NET bandwidth using `cleos` command line tool or using a wallet that implements this functionality. +Stake resource for your account -TO DO: verify and correct the next url -To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](https://eosio.github.io/eos/cleos/how-to-stake-resource) +## Before you begin -To stake tokens for CPU and/or NET bandwidth using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file +* Install the currently supported version of cleos + +* Ensure the reference system contracts from `eosio.contracts` repository is deployed and used to manage system resources + +* Understand the following: + * What is an account + * What is network bandwidth + * What is CPU bandwidth + +## Steps + +Stake 0.01 SYS network bandwidth for `alice` + +```shell +cleos system delegatebw alice alice "0 SYS" "0.01 SYS" +``` + +Stake 0.01 SYS CPU bandwidth for `alice`: + +```shell +cleos system delegatebw alice alice "0.01 SYS" "0 SYS" +``` \ No newline at end of file diff --git a/docs/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md index d27cccac0..62654ba7c 100644 --- a/docs/03_guides/04_how-to-vote.md +++ b/docs/03_guides/04_how-to-vote.md @@ -1,8 +1,30 @@ -## How to vote +## Goal -You can vote using `cleos` command line tool or using a wallet that implements the vote functionality. +Vote for a block producer -TO DO: verify and correct the next url -To vote using `cleos` check [how to vote](https://eosio.github.io/eos/cleos/how-to-vote) +## Before you begin -To vote using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file +* Install the current supported version of cleos + +* Ensure the reference system contracts from `eosio.contracts` repository is deployed and used to manage system resources + +* Understand the following: + * What is a block producer + * How does voting works + +* Unlock your wallet + +## Steps + +Assume you are going to vote for blockproducer1 and blockproducer2 from an account called `eosiotestts2`, execute the following: + +```bash +cleos system voteproducer prods eosiotestts2 blockproducer1 blockproducer2 +``` + +You should see something like below: + +```bash +executed transaction: 2d8b58f7387aef52a1746d7a22d304bbbe0304481d7751fc4a50b619df62676d 128 bytes 374 us +# eosio <= eosio::voteproducer {"voter":"eosiotestts2","proxy":"","producers":["blockproducer1","blockproducer2"]} +``` \ No newline at end of file From 321929954bedcf5ec8ddcf1044dc37f246566811 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 31 Oct 2019 16:47:54 +0200 Subject: [PATCH 62/97] clean up one remaining TO DO. --- docs/03_guides/01_upgrading-the-eosio.system-contract.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/03_guides/01_upgrading-the-eosio.system-contract.md b/docs/03_guides/01_upgrading-the-eosio.system-contract.md index 953ce0730..2bd712fb4 100644 --- a/docs/03_guides/01_upgrading-the-eosio.system-contract.md +++ b/docs/03_guides/01_upgrading-the-eosio.system-contract.md @@ -73,8 +73,6 @@ Then each of the top 21 block producers should do the following: 5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: -TO DO: Shouldn't one of the files be upgrade_system_contract_trx.json? - ``` $ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json 2,4c2,4 From d1cf46b9c9424399617c3256db950dcf93d39d80 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 31 Oct 2019 17:41:00 +0200 Subject: [PATCH 63/97] final touches: use build everywhere instead of a mix of build and compile, fix some headings --- README.md | 2 +- ...le-and-deploy.md => 02_build-and-deploy.md} | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) rename docs/{02_compile-and-deploy.md => 02_build-and-deploy.md} (85%) diff --git a/README.md b/README.md index 04e491a69..510178dd0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) * [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) (optional dependency only needed to build unit tests) -To build the contracts follow the instructions in [`Compile and deploy` section](./docs/02_compile-and-deploy.md). +To build the contracts follow the instructions in [`Build and deploy` section](./docs/02_build-and-deploy.md). ## Contributing diff --git a/docs/02_compile-and-deploy.md b/docs/02_build-and-deploy.md similarity index 85% rename from docs/02_compile-and-deploy.md rename to docs/02_build-and-deploy.md index 06fbd8610..b61b15133 100644 --- a/docs/02_compile-and-deploy.md +++ b/docs/02_build-and-deploy.md @@ -1,4 +1,4 @@ -## How to compile the eosio.contracts +## How to build the eosio.contracts ### Preconditions Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases) to install it. To verify if you have `eosio.cdt` installed and its version run the following command @@ -18,7 +18,7 @@ Run the `build.sh` script in the top directory to build all the contracts. #### Build contracts manually -To compile the `eosio.contracts` execute the following commands. +To build the `eosio.contracts` execute the following commands. On all platforms except macOS: ```sh @@ -42,36 +42,38 @@ make -j$(sysctl -n hw.ncpu) cd .. ``` -### After build: +#### After build: * If the build was configured to also build unit tests, the unit tests executable is placed in the _build/tests_ folder and is named __unit_test__. * The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. * Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. -## To deploy eosio.bios contract execute the following command: +## How to deploy the eosio.contracts + +### To deploy eosio.bios contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testerbios` ``` cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios ``` -## To deploy eosio.msig contract execute the following command: +### To deploy eosio.msig contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testermsig` ``` cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig ``` -## To deploy eosio.system contract execute the following command: +### To deploy eosio.system contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testersystem` ``` cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem ``` -## To deploy eosio.token contract execute the following command: +### To deploy eosio.token contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testertoken` ``` cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken ``` -## To deploy eosio.wrap contract execute the following command: +### To deploy eosio.wrap contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testerwrap` ``` cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap From 4292fc1c10087cd7da0c26bf5dbe7b42a2717822 Mon Sep 17 00:00:00 2001 From: dskvr Date: Fri, 1 Nov 2019 09:10:17 -0400 Subject: [PATCH 64/97] Do not provide documentation for get_core_symbol during this release. --- .../eosio.system/include/eosio.system/eosio.system.hpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index fa567ec0e..32cd62365 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -85,7 +85,6 @@ namespace eosiosystem { * - Users can bid on premium names. * - A resource exchange system (REX) allows token holders to lend their tokens, * and users to rent CPU and Network resources in return for a market-determined fee. - * @{ */ // A name bid, which consists of: @@ -471,11 +470,8 @@ namespace eosiosystem { system_contract( name s, name code, datastream ds ); ~system_contract(); - /** - * Returns the core symbol by system account name - * - * @param system_account - the system account to get the core symbol for. - */ + // Returns the core symbol by system account name + // @param system_account - the system account to get the core symbol for. static symbol get_core_symbol( name system_account = "eosio"_n ) { rammarket rm(system_account, system_account.value); const static auto sym = get_core_symbol( rm ); From d76c92ceb4718df2f006449eace9a16bb3b15c15 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 6 Nov 2019 11:40:44 -0500 Subject: [PATCH 65/97] Fix for determining eosio and cdt versions required for forked PRs. --- .cicd/build.sh | 3 ++- .cicd/helpers/dependency-info.sh | 17 ++++++++++------- .travis.yml | 5 +---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index bf97c186b..eb2228595 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -15,7 +15,7 @@ else export DOCKER_IMAGE fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/\\\$(ls /usr/opt/eosio.cdt/)/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" @@ -31,4 +31,5 @@ while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMA sleep 60 done # run +echo "docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\"" eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index d24f74b32..940241d56 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -14,15 +14,18 @@ else exit 1 fi # search GitHub for commit hash by tag and branch, preferring tag if both match -if [[ $TRAVIS ]]; then - CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') -else +if [[ "$BUILDKITE" == 'true' ]]; then CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already + test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already +else + git clone https://github.com/EOSIO/eosio.cdt && cd eosio.cdt + git pull && git checkout $CDT_VERSION + CDT_COMMIT=$(git rev-parse --verify HEAD) + EOSIO_COMMIT=$(echo $EOSIO_VERSION | sed 's/\//\_/') + cd .. fi -test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already -echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." -test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." +echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt-ubuntu-18.04_amd64.deb" \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 516355254..c1d0e8ee1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,4 @@ matrix: script: ". ./.cicd/build.sh && ./.cicd/test.sh" notifications: webhooks: - secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= -env: - global: - secure: jE/hVrQwgGs4KDdBqtiaGb9QE7xg8tn9NK2xMyedsi1CzqSZwl1iLjoefD4nH2wYRCGWfTBFES7QtJbj7SZK0+eobwQMO+jyXSOBd8D8HqcT37UMOPYW72YY2UuZpSCinuLHkZxZnb5dGfMqXDIZ3Y3GIgxOAd2+a0Y6xLt0dfZvh4OH8KVc/wWtuAjh0kMYEoQV9gEyok7xnXNjSLbAbkVslQBKHv451oi8saIGQbFC3b1KSGlE9LBv0QAR9MLXlkYMF3tAfegTGzx/NUIwdOOJ6XoPWoUGWV/u/nWexjHwsb1MwqQHN+LWHRM39ehL46na4m32S/ro3wHmBXnxlF3ys8QH0PEpfJL+r8aKGOv3pmWE//x+Ias6K6RWzTMLRFqlDPGTAGgMRGFiyGhT1aRHXD+mC2RppXptBST9brhE7+lyVqzKYFFHi0SHxfRsSQLgGhIJTMBr2Jj5ORlT86BWdxj3P8VOitKif/RP1zuJBKr78EyLGDPvsJhmot/gPg3VAo2R+cyFqVBWig2PC2ylneSS2DptMV6qLlujA+Fr38diYacsMqhej3ukqVZGaOecSIJXweJQ+7Y9SvGQDeAH8gEzgLLlkNrwpaFtLpxUqHrGWKJHUS8oKtleTznoK1Ck9Es2JTG2Tr4gVHk0OCIfc3hZRQl5Kj7AVi20Tec= \ No newline at end of file + secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= \ No newline at end of file From b4d0ed186111012af28a9a207fa9ebc454b06329 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 6 Nov 2019 15:09:01 -0500 Subject: [PATCH 66/97] Determine EOSIO version same way as CDT. --- .cicd/helpers/dependency-info.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 940241d56..c0f526ac3 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -23,7 +23,10 @@ else git clone https://github.com/EOSIO/eosio.cdt && cd eosio.cdt git pull && git checkout $CDT_VERSION CDT_COMMIT=$(git rev-parse --verify HEAD) - EOSIO_COMMIT=$(echo $EOSIO_VERSION | sed 's/\//\_/') + cd .. + git clone https://github.com/EOSIO/eos && cd eos + git pull && git checkout $EOSIO_VERSION + EOSIO_COMMIT=$(git rev-parse --verify HEAD) cd .. fi echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." From 44c532b4a9c0773c49bb591aafea8502e042d390 Mon Sep 17 00:00:00 2001 From: Nathan Pierce Date: Thu, 7 Nov 2019 10:15:58 -0500 Subject: [PATCH 67/97] gke -> eks --- .cicd/pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 009fe0ef9..801c8d331 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -7,7 +7,7 @@ steps: tar -pczf build.tar.gz build buildkite-agent artifact upload build.tar.gz agents: - queue: "automation-eos-builder-fleet" + queue: "automation-eks-eos-builder-fleet" timeout: "${TIMEOUT:-40}" skip: "$SKIP_UBUNTU_18" @@ -19,7 +19,7 @@ steps: tar -xzf build.tar.gz ./.cicd/test.sh agents: - queue: "automation-eos-builder-fleet" + queue: "automation-eks-eos-builder-fleet" timeout: "${TIMEOUT:-10}" skip: "$SKIP_UBUNTU_18" @@ -33,6 +33,6 @@ steps: echo '+++ :javascript: Running test-metrics.js' node --max-old-space-size=32768 test-metrics.js agents: - queue: "automation-eos-builder-fleet" + queue: "automation-eks-eos-builder-fleet" timeout: 10 soft_fail: true \ No newline at end of file From 1c9029ca2f085d525de11b8f1be4136b5e00b262 Mon Sep 17 00:00:00 2001 From: Nathan Pierce Date: Thu, 7 Nov 2019 10:53:54 -0500 Subject: [PATCH 68/97] testers --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 801c8d331..9c9a4ab21 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -19,7 +19,7 @@ steps: tar -xzf build.tar.gz ./.cicd/test.sh agents: - queue: "automation-eks-eos-builder-fleet" + queue: "automation-eks-eos-tester-fleet" timeout: "${TIMEOUT:-10}" skip: "$SKIP_UBUNTU_18" @@ -33,6 +33,6 @@ steps: echo '+++ :javascript: Running test-metrics.js' node --max-old-space-size=32768 test-metrics.js agents: - queue: "automation-eks-eos-builder-fleet" + queue: "automation-eks-eos-tester-fleet" timeout: 10 soft_fail: true \ No newline at end of file From e71acbe194fc86188ca1dc28f736c35b8603cd0a Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 10 Nov 2019 22:40:28 -0500 Subject: [PATCH 69/97] use authorization of bidder for bidrefund deferred transaction --- contracts/eosio.system/src/name_bidding.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/name_bidding.cpp b/contracts/eosio.system/src/name_bidding.cpp index d08aed653..4c01f353a 100644 --- a/contracts/eosio.system/src/name_bidding.cpp +++ b/contracts/eosio.system/src/name_bidding.cpp @@ -50,7 +50,7 @@ namespace eosiosystem { } eosio::transaction t; - t.actions.emplace_back( permission_level{get_self(), active_permission}, + t.actions.emplace_back( permission_level{current->high_bidder, active_permission}, get_self(), "bidrefund"_n, std::make_tuple( current->high_bidder, newname ) ); From ee98a92a2c49d7ec5d47a4718a62a3ac99955752 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 12 Nov 2019 15:13:42 -0500 Subject: [PATCH 70/97] bump version to v1.9.0-rc2 --- CMakeLists.txt | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ef311a3b..058632c4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc1) +set(VERSION_SUFFIX rc2) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 328676374..482359d6a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc1 +## Version : 1.9.0-rc2 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. @@ -16,7 +16,7 @@ The following unprivileged contract(s) are also part of the system. Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) -* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) (optional dependency only needed to build unit tests) +* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc2) (optional dependency only needed to build unit tests) To build the contracts follow the instructions in [`Build and deploy` section](./docs/02_build-and-deploy.md). From 61436b0a35793b530767a9ea7686df091c1d7385 Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 30 Nov 2019 18:07:41 -0500 Subject: [PATCH 71/97] avoid updating total_activated_stake after activation --- contracts/eosio.system/src/delegate_bandwidth.cpp | 2 +- contracts/eosio.system/src/producer_pay.cpp | 6 +++--- contracts/eosio.system/src/voting.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index e1ecbd1f2..d15a8202a 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -392,7 +392,7 @@ namespace eosiosystem { check( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); check( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); check( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); - check( _gstate.total_activated_stake >= min_activated_stake, + check( _gstate.thresh_activated_stake_time != time_point(), "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index cf7e2ddeb..4db2f7740 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -21,8 +21,8 @@ namespace eosiosystem { // is eventually completely removed, at which point this line can be removed. _gstate2.last_block_num = timestamp; - /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < min_activated_stake ) + /** until activation, no new rewards are paid */ + if( _gstate.thresh_activated_stake_time == time_point() ) return; if( _gstate.last_pervote_bucket_fill == time_point() ) /// start the presses @@ -71,7 +71,7 @@ namespace eosiosystem { const auto& prod = _producers.get( owner.value ); check( prod.active(), "producer does not have an active key" ); - check( _gstate.total_activated_stake >= min_activated_stake, + check( _gstate.thresh_activated_stake_time != time_point(), "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" ); const auto ct = current_time_point(); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index d26e187c6..a42239db5 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -231,13 +231,13 @@ namespace eosiosystem { check( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" ); /** - * The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until - * after total_activated_stake hits threshold, we can use last_vote_weight to determine that this is + * The first time someone votes we calculate and set last_vote_weight. Since they cannot unstake until + * after the chain has been activated, we can use last_vote_weight to determine that this is * their first vote and should consider their stake activated. */ - if( voter->last_vote_weight <= 0.0 ) { + if( _gstate.thresh_activated_stake_time == time_point() && voter->last_vote_weight <= 0.0 ) { _gstate.total_activated_stake += voter->staked; - if( _gstate.total_activated_stake >= min_activated_stake && _gstate.thresh_activated_stake_time == time_point() ) { + if( _gstate.total_activated_stake >= min_activated_stake ) { _gstate.thresh_activated_stake_time = current_time_point(); } } From 2dc0c72639f18b9bd35c72ee7c5a28ae71786c7e Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 2 Dec 2019 14:42:53 -0500 Subject: [PATCH 72/97] bump version to v1.9.0-rc3 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 058632c4b..944d08c2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc2) +set(VERSION_SUFFIX rc3) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 482359d6a..4649af9d1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc2 +## Version : 1.9.0-rc3 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. From 01e941eab3729da1333ace60dec0401ac4e940fc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 13 Nov 2019 17:16:53 -0500 Subject: [PATCH 73/97] REX changes - initial commit --- .../include/eosio.system/eosio.system.hpp | 14 ++++++ contracts/eosio.system/src/eosio.system.cpp | 2 +- contracts/eosio.system/src/rex.cpp | 50 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 32cd62365..cdedbae09 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -337,6 +337,17 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; + struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { + uint8_t version = 0; + int64_t current_rate_of_increase = 0; + time_point_sec last_update_time; + std::map return_buckets; + + uint64_t primary_key()const { return 0; } + }; + + typedef eosio::multi_index< "rexretpool"_n, rex_return_pool > rex_return_pool_table; + // `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: // - `version` defaulted to zero, // - `owner` the owner of the rex fund, @@ -447,6 +458,7 @@ namespace eosiosystem { eosio_global_state4 _gstate4; rammarket _rammarket; rex_pool_table _rexpool; + rex_return_pool_table _rexretpool; rex_fund_table _rexfunds; rex_balance_table _rexbalance; rex_order_table _rexorders; @@ -1143,6 +1155,7 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); + void update_rex_pool(); void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); void check_voting_requirement( const name& owner, const char* error_msg = "must vote for at least 21 producers or for a proxy before buying REX" )const; @@ -1164,6 +1177,7 @@ namespace eosiosystem { static time_point_sec get_rex_maturity(); asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); asset add_to_rex_pool( const asset& payment ); + void add_to_rex_return_pool( const asset& fee ); void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index b05c5f011..a6af9e0d0 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -26,11 +26,11 @@ namespace eosiosystem { _global4(get_self(), get_self().value), _rammarket(get_self(), get_self().value), _rexpool(get_self(), get_self().value), + _rexretpool(get_self(), get_self().value), _rexfunds(get_self(), get_self().value), _rexbalance(get_self(), get_self().value), _rexorders(get_self(), get_self().value) { - //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 4a4596e25..c55c798ab 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -513,6 +513,8 @@ namespace eosiosystem { { check( rex_system_initialized(), "rex system not initialized yet" ); + update_rex_pool(); + const auto& pool = _rexpool.begin(); auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { @@ -616,6 +618,43 @@ namespace eosiosystem { } + void system_contract::update_rex_pool() + { + const int32_t num_of_days = 30; + const time_point_sec ct = current_time_point(); + const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / ( num_of_days * seconds_per_day ); + const auto time_threshold = ct - eosio::days(num_of_days); + + int64_t change = change_estimate; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { + auto& return_buckets = return_pool.return_buckets; + auto iter= return_buckets.begin(); + while ( iter!= return_buckets.begin() && iter->first <= time_threshold ) { + auto next = iter; + ++next; + const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); + const int64_t rate = iter->second; + int64_t surplus = ( uint128_t(overtime) * rate ) / ( num_of_days * seconds_per_day ); + change -= surplus; + return_pool.current_rate_of_increase -= rate; + return_buckets.erase(iter); + iter = next; + } + return_pool.last_update_time = ct; + }); + + if ( change <= 0 ) { + return; + } + + _rexpool.modify(_rexpool.begin(), same_payer, [&](auto& pool) { + pool.total_unlent.amount += change; + pool.total_lendable = pool.total_unlent + pool.total_lent; + }); + } + template int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) { @@ -961,6 +1000,17 @@ namespace eosiosystem { return rex_received; } + void system_contract::add_to_rex_return_pool( const asset& fee ) + { + update_rex_pool(); + const uint32_t cts = current_time_point().sec_since_epoch(); + time_point_sec effective_time{ cts - cts % seconds_per_day }; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { + return_pool.return_buckets[effective_time] += fee.amount; + return_pool.current_rate_of_increase += fee.amount; + }); + } + /** * @brief Updates owner REX balance upon buying REX tokens * From 5348617d847bf98d329e956c8ebd86223d8ea2ef Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 15 Nov 2019 18:06:42 -0500 Subject: [PATCH 74/97] REX changes --- .../include/eosio.system/eosio.system.hpp | 1 + contracts/eosio.system/src/rex.cpp | 69 +++++++++++++++---- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index cdedbae09..566362f7e 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,6 +340,7 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; int64_t current_rate_of_increase = 0; + int64_t residue = 0; time_point_sec last_update_time; std::map return_buckets; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index c55c798ab..f9ba8cabe 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -452,15 +452,13 @@ namespace eosiosystem { */ void system_contract::add_loan_to_rex_pool( const asset& payment, int64_t rented_tokens, bool new_loan ) { + add_to_rex_return_pool( payment ); _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rt ) { // add payment to total_rent rt.total_rent.amount += payment.amount; // move rented_tokens from total_unlent to total_lent rt.total_unlent.amount -= rented_tokens; rt.total_lent.amount += rented_tokens; - // add payment to total_unlent - rt.total_unlent.amount += payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; // increment loan_num if a new loan is being created if ( new_loan ) { rt.loan_num++; @@ -620,18 +618,39 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - const int32_t num_of_days = 30; - const time_point_sec ct = current_time_point(); + const int32_t num_of_days = 30; + const time_point_sec ct = current_time_point(); + + if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { + return; + } + + if ( _rexretpool.begin()->residue > 0 ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { + pool.total_unlent.amount += _rexretpool.begin()->residue; + pool.total_lendable = pool.total_unlent + pool.total_lent; + }); + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + return_pool.residue = 0; + }); + } + + if ( _rexretpool.begin()->return_buckets.empty() || ct <= _rexretpool.begin()->return_buckets.begin()->first ) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + return_pool.last_update_time = ct; + }); + return; + } const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / ( num_of_days * seconds_per_day ); const auto time_threshold = ct - eosio::days(num_of_days); int64_t change = change_estimate; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { auto& return_buckets = return_pool.return_buckets; - auto iter= return_buckets.begin(); - while ( iter!= return_buckets.begin() && iter->first <= time_threshold ) { + auto iter = return_buckets.begin(); + while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); @@ -649,7 +668,7 @@ namespace eosiosystem { return; } - _rexpool.modify(_rexpool.begin(), same_payer, [&](auto& pool) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { pool.total_unlent.amount += change; pool.total_lendable = pool.total_unlent + pool.total_lent; }); @@ -1003,11 +1022,33 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - const uint32_t cts = current_time_point().sec_since_epoch(); - time_point_sec effective_time{ cts - cts % seconds_per_day }; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { - return_pool.return_buckets[effective_time] += fee.amount; - return_pool.current_rate_of_increase += fee.amount; + const uint32_t num_of_days = 30; + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + + if ( _rexretpool.begin() == _rexretpool.end() ) { + _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { + return_pool.last_update_time = ct; + }); + } + + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + time_point_sec effective_time{ cts - cts % seconds_per_day }; + auto& return_buckets = return_pool.return_buckets; + auto& current_rate_of_increase = return_pool.current_rate_of_increase; + auto iter = return_buckets.find( effective_time ); + if ( iter != return_buckets.end() ) { + iter->second += fee.amount; + } else { + int64_t residue = 0; + if ( !return_buckets.empty() ) { + uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); + residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / ( num_of_days * seconds_per_day ); + } + return_pool.residue += residue; + current_rate_of_increase += return_buckets.rbegin()->second; + return_buckets[effective_time] = fee.amount; + } }); } From 1a998d4dacaacc5836ee064da4bbd0fa6ca348e1 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 19 Nov 2019 10:23:31 -0500 Subject: [PATCH 75/97] Changes to REX return buckets --- .../include/eosio.system/eosio.system.hpp | 2 ++ contracts/eosio.system/src/rex.cpp | 27 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 566362f7e..b488caae5 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -61,6 +61,7 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_year = 52 * 7 * 24 * 3600; static constexpr uint32_t seconds_per_day = 24 * 3600; + static constexpr uint32_t seconds_per_hour = 3600; static constexpr int64_t useconds_per_year = int64_t(seconds_per_year) * 1000'000ll; static constexpr int64_t useconds_per_day = int64_t(seconds_per_day) * 1000'000ll; static constexpr uint32_t blocks_per_day = 2 * seconds_per_day; // half seconds per day @@ -339,6 +340,7 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; + uint8_t hours_per_bucket = 12; int64_t current_rate_of_increase = 0; int64_t residue = 0; time_point_sec last_update_time; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index f9ba8cabe..58937b59a 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -618,8 +618,8 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - const int32_t num_of_days = 30; - const time_point_sec ct = current_time_point(); + constexpr int32_t total_duration = 30 * seconds_per_day; + const time_point_sec ct = current_time_point(); if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { return; @@ -641,10 +641,10 @@ namespace eosiosystem { }); return; } - const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / ( num_of_days * seconds_per_day ); - const auto time_threshold = ct - eosio::days(num_of_days); + const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / total_duration; + const time_point_sec time_threshold{ ct.sec_since_epoch() - total_duration }; int64_t change = change_estimate; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { @@ -655,7 +655,7 @@ namespace eosiosystem { ++next; const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); const int64_t rate = iter->second; - int64_t surplus = ( uint128_t(overtime) * rate ) / ( num_of_days * seconds_per_day ); + const int64_t surplus = ( uint128_t(overtime) * rate ) / total_duration; change -= surplus; return_pool.current_rate_of_increase -= rate; return_buckets.erase(iter); @@ -1022,9 +1022,9 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - const uint32_t num_of_days = 30; - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); + constexpr uint32_t total_duration = 30 * seconds_per_day; + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { @@ -1032,8 +1032,11 @@ namespace eosiosystem { }); } + const uint8_t hours_per_bucket = _rexretpool.begin()->hours_per_bucket; + const uint32_t bucket_interval = hours_per_bucket * seconds_per_hour; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - time_point_sec effective_time{ cts - cts % seconds_per_day }; + time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; auto& return_buckets = return_pool.return_buckets; auto& current_rate_of_increase = return_pool.current_rate_of_increase; auto iter = return_buckets.find( effective_time ); @@ -1043,7 +1046,7 @@ namespace eosiosystem { int64_t residue = 0; if ( !return_buckets.empty() ) { uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); - residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / ( num_of_days * seconds_per_day ); + residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / total_duration; } return_pool.residue += residue; current_rate_of_increase += return_buckets.rbegin()->second; From c255aa89e1c127d2becfd946a6a61646b3c972fd Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 19 Nov 2019 18:26:40 -0500 Subject: [PATCH 76/97] REX changes testing --- contracts/eosio.system/src/rex.cpp | 8 ++++---- tests/eosio.system_tester.hpp | 21 +++++++++++++++++++++ tests/eosio.system_tests.cpp | 17 ++++++++++++++++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 58937b59a..aa268529a 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -1032,8 +1032,7 @@ namespace eosiosystem { }); } - const uint8_t hours_per_bucket = _rexretpool.begin()->hours_per_bucket; - const uint32_t bucket_interval = hours_per_bucket * seconds_per_hour; + const uint32_t bucket_interval = _rexretpool.begin()->hours_per_bucket * seconds_per_hour; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; @@ -1047,9 +1046,10 @@ namespace eosiosystem { if ( !return_buckets.empty() ) { uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / total_duration; + current_rate_of_increase += return_buckets.rbegin()->second; } - return_pool.residue += residue; - current_rate_of_increase += return_buckets.rbegin()->second; + return_pool.residue += residue; + // current_rate_of_increase += return_buckets.rbegin()->second; return_buckets[effective_time] = fee.amount; } }); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 753df1a1f..a4795c03b 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -666,6 +666,27 @@ class eosio_system_tester : public TESTER { return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer_max_time ); } + fc::variant get_rex_return_pool() const { + vector data; + const auto& db = control->db(); + namespace chain = eosio::chain; + const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(rexretpool) ) ); + if ( !t_id ) { + return fc::variant(); + } + + const auto& idx = db.get_index(); + + auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); + if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { + return fc::variant(); + } + + data.resize( itr->value.size() ); + memcpy( data.data(), itr->value.data(), data.size() ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer_max_time ); + } + void setup_rex_accounts( const std::vector& accounts, const asset& init_balance, const asset& net = core_sym::from_string("80.0000"), diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index c78439a1d..82821a15d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3708,6 +3708,7 @@ BOOST_FIXTURE_TEST_CASE( rex_auth, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; @@ -3945,13 +3946,15 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); + BOOST_REQUIRE( get_rex_return_pool().is_null() ); + { // bob rents cpu for carol const asset fee = core_sym::from_string("17.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); BOOST_REQUIRE_EQUAL( init_balance - fee, get_rex_fund(bob) ); rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 17 + BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); // 65 BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); BOOST_REQUIRE_EQUAL( expected_total_lent, @@ -3959,6 +3962,12 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); + auto rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE( !rex_return_pool.is_null() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + + // test that carol's resource limits have been updated properly BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); @@ -3973,6 +3982,12 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { produce_block( fc::days(20) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE( !rex_return_pool.is_null() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + produce_block( fc::days(10) ); // alice is finally able to sellrex, she gains the fee paid by bob BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); From 9f9e62d479723fa7ae70d2d7b47f0fa4815a1776 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Nov 2019 09:51:50 -0500 Subject: [PATCH 77/97] REX changes testing - 2 --- .../include/eosio.system/eosio.system.hpp | 4 +- contracts/eosio.system/src/rex.cpp | 46 +++++++++++-------- tests/eosio.system_tests.cpp | 11 +++-- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index b488caae5..1f05f34dc 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,12 +340,14 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; - uint8_t hours_per_bucket = 12; int64_t current_rate_of_increase = 0; int64_t residue = 0; time_point_sec last_update_time; std::map return_buckets; + static constexpr uint32_t total_duration = 30 * seconds_per_day; + static constexpr uint8_t hours_per_bucket = 12; + uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index aa268529a..7d4951a1b 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -618,8 +618,7 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - constexpr int32_t total_duration = 30 * seconds_per_day; - const time_point_sec ct = current_time_point(); + const time_point_sec ct = current_time_point(); if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { return; @@ -634,17 +633,24 @@ namespace eosiosystem { return_pool.residue = 0; }); } - + /* if ( _rexretpool.begin()->return_buckets.empty() || ct <= _rexretpool.begin()->return_buckets.begin()->first ) { _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { return_pool.last_update_time = ct; }); return; } - const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + */ + if ( _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first ) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + return_pool.current_rate_of_increase += return_pool.return_buckets.rbegin()->second; + }); + } + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / total_duration; - const time_point_sec time_threshold{ ct.sec_since_epoch() - total_duration }; + const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; int64_t change = change_estimate; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { @@ -655,7 +661,7 @@ namespace eosiosystem { ++next; const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); const int64_t rate = iter->second; - const int64_t surplus = ( uint128_t(overtime) * rate ) / total_duration; + const int64_t surplus = ( uint128_t(overtime) * rate ) / rex_return_pool::total_duration; change -= surplus; return_pool.current_rate_of_increase -= rate; return_buckets.erase(iter); @@ -1022,35 +1028,39 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - constexpr uint32_t total_duration = 30 * seconds_per_day; - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; + const time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { - return_pool.last_update_time = ct; + return_pool.last_update_time = effective_time; }); } - const uint32_t bucket_interval = _rexretpool.begin()->hours_per_bucket * seconds_per_hour; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; auto& return_buckets = return_pool.return_buckets; auto& current_rate_of_increase = return_pool.current_rate_of_increase; auto iter = return_buckets.find( effective_time ); if ( iter != return_buckets.end() ) { iter->second += fee.amount; } else { + // create a new bucket + // but first process the previous bucket if it exists int64_t residue = 0; if ( !return_buckets.empty() ) { uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); - residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / total_duration; - current_rate_of_increase += return_buckets.rbegin()->second; + if ( interval < rex_return_pool::total_duration ) { + residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / rex_return_pool::total_duration; + current_rate_of_increase += return_buckets.rbegin()->second; + } else { + residue = return_buckets.rbegin()->second; + // erase rbegin + } } return_pool.residue += residue; - // current_rate_of_increase += return_buckets.rbegin()->second; - return_buckets[effective_time] = fee.amount; + return_buckets.emplace( effective_time, fee.amount ); } }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 82821a15d..0915cd2af 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3985,14 +3985,17 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(10) ); // alice is finally able to sellrex, she gains the fee paid by bob BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( init_balance + fee, get_rex_fund(alice) ); + auto expected_rex_fund = (init_balance + fee).get_amount(); + auto actual_rex_fund = get_rex_fund(alice).get_amount(); + BOOST_REQUIRE_EQUAL( true, within_one( expected_rex_fund, actual_rex_fund ) ); + BOOST_REQUIRE( actual_rex_fund <= expected_rex_fund ); // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); @@ -4050,7 +4053,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { const asset fee = core_sym::from_string("7.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); produce_block( fc::days(5) ); From 457d0ad7448922cfc09a09fe3d4ff8a703b067c5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 27 Nov 2019 23:27:34 -0700 Subject: [PATCH 78/97] REX changes - fix unit tests --- .../include/eosio.system/eosio.system.hpp | 3 +- contracts/eosio.system/src/rex.cpp | 79 ++++++------------- tests/eosio.system_tests.cpp | 70 ++++++++++------ 3 files changed, 69 insertions(+), 83 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 1f05f34dc..a8e178313 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,9 +340,8 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; - int64_t current_rate_of_increase = 0; - int64_t residue = 0; time_point_sec last_update_time; + int64_t current_rate_of_increase = 0; std::map return_buckets; static constexpr uint32_t total_duration = 30 * seconds_per_day; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 7d4951a1b..86b33c619 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -624,50 +624,40 @@ namespace eosiosystem { return; } - if ( _rexretpool.begin()->residue > 0 ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { - pool.total_unlent.amount += _rexretpool.begin()->residue; - pool.total_lendable = pool.total_unlent + pool.total_lent; - }); - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - return_pool.residue = 0; - }); - } - /* - if ( _rexretpool.begin()->return_buckets.empty() || ct <= _rexretpool.begin()->return_buckets.begin()->first ) { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - return_pool.last_update_time = ct; - }); - return; - } - */ - if ( _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first ) { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - return_pool.current_rate_of_increase += return_pool.return_buckets.rbegin()->second; + const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() + && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first + && _rexretpool.begin()->return_buckets.rbegin()->first <= ct; + int64_t new_bucket_overestimate = 0; + if ( new_return_bucket ) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; + const uint32_t dt = rp.return_buckets.rbegin()->first.sec_since_epoch() - rp.last_update_time.sec_since_epoch(); + new_bucket_overestimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; }); } const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration + - new_bucket_overestimate; const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; int64_t change = change_estimate; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - auto& return_buckets = return_pool.return_buckets; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + auto& return_buckets = rp.return_buckets; auto iter = return_buckets.begin(); while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; - const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); + const uint32_t overtime = ct.sec_since_epoch() - ( iter->first.sec_since_epoch() + rex_return_pool::total_duration ); const int64_t rate = iter->second; const int64_t surplus = ( uint128_t(overtime) * rate ) / rex_return_pool::total_duration; - change -= surplus; - return_pool.current_rate_of_increase -= rate; + change -= surplus; + rp.current_rate_of_increase -= rate; return_buckets.erase(iter); iter = next; } - return_pool.last_update_time = ct; + rp.last_update_time = ct; }); if ( change <= 0 ) { @@ -1029,39 +1019,18 @@ namespace eosiosystem { { update_rex_pool(); - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); + const uint32_t cts = current_time_point().sec_since_epoch(); const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; const time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; + if ( _rexretpool.begin() == _rexretpool.end() ) { - _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { - return_pool.last_update_time = effective_time; + _rexretpool.emplace( get_self(), [&]( auto& rp ) { + rp.last_update_time = effective_time; }); } - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - auto& return_buckets = return_pool.return_buckets; - auto& current_rate_of_increase = return_pool.current_rate_of_increase; - auto iter = return_buckets.find( effective_time ); - if ( iter != return_buckets.end() ) { - iter->second += fee.amount; - } else { - // create a new bucket - // but first process the previous bucket if it exists - int64_t residue = 0; - if ( !return_buckets.empty() ) { - uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); - if ( interval < rex_return_pool::total_duration ) { - residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / rex_return_pool::total_duration; - current_rate_of_increase += return_buckets.rbegin()->second; - } else { - residue = return_buckets.rbegin()->second; - // erase rbegin - } - } - return_pool.residue += residue; - return_buckets.emplace( effective_time, fee.amount ); - } + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.return_buckets[effective_time] += fee.amount; }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0915cd2af..538fd6098 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3964,9 +3964,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); // test that carol's resource limits have been updated properly BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); @@ -3985,7 +3983,6 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(10) ); @@ -4113,30 +4110,31 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("20000.0000") ) ); } - const asset rent_payment = core_sym::from_string("40000.0000"); + produce_block( fc::days(25) ); + const asset rent_payment = core_sym::from_string("40000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); + produce_block( fc::days(4) ); + + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); + const auto init_rex_pool = get_rex_pool(); const int64_t total_lendable = init_rex_pool["total_lendable"].as().get_amount(); const int64_t total_rex = init_rex_pool["total_rex"].as().get_amount(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * total_lendable ) / total_rex; - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); - produce_block( fc::days(5) ); - init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); @@ -4153,7 +4151,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); // wait for 30 days minus 1 hour - produce_block( fc::hours(19*24 + 23) ); + produce_block( fc::hours(23) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); @@ -4176,21 +4174,28 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { } { + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); + BOOST_TEST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); } + produce_blocks(2); + produce_block( fc::hours(13) ); + produce_blocks(2); + produce_block( fc::days(30) ); + produce_blocks(2); + { auto trace1 = base_tester::push_action( config::system_account_name, N(updaterex), bob, mvo()("owner", bob) ); auto trace2 = base_tester::push_action( config::system_account_name, N(updaterex), carol, mvo()("owner", carol) ); @@ -4318,7 +4323,8 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { } // wait for 30 days, frank's loan will be renewed at the current price - produce_block( fc::hours(30*24 + 1) ); + produce_block( fc::minutes(30*24*60 - 1) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); rex_pool = get_rex_pool(); { int64_t unlent_tokens = bancor_convert( rex_pool["total_unlent"].as().get_amount(), @@ -4330,6 +4336,8 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { payment.get_amount() ); } + produce_block( fc::minutes(2) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); loan_info = get_cpu_loan(1); @@ -4818,15 +4826,17 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const int64_t init_stake = get_voter_info( alice )["staked"].as(); + // alice buys rex const asset payment = core_sym::from_string("25000.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); + // emily rents cpu const asset fee = core_sym::from_string("50.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, fee ) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( payment + fee, get_rex_vote_stake(alice) ); + BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers @@ -4846,9 +4856,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); + vote( alice, { producer_names.begin(), producer_names.begin() + 20 } ) ); BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4856,23 +4866,25 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to == get_producer_info(producer_names[20])["total_votes"].as() ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - produce_block( fc::days(20) ); + produce_block( fc::days(10) ); BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); + produce_block( fc::hours(19 * 24 + 23) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); const int64_t total_lendable = current_rex_pool["total_lendable"].as().get_amount(); const int64_t total_rex = current_rex_pool["total_rex"].as().get_amount(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_rex.get_amount()) * total_lendable ) / total_rex; - produce_block( fc::days(5) ); const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); - BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ); + BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ) ); BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4922,18 +4934,20 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( purchase.get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); const auto init_rex_pool = get_rex_pool(); const asset rent = core_sym::from_string("25.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); + + produce_block( fc::days(31) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const auto curr_rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( curr_rex_pool["total_lendable"].as(), init_rex_pool["total_lendable"].as() + rent ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + + BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); BOOST_REQUIRE_EQUAL( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); BOOST_REQUIRE_EQUAL( purchase + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == @@ -4945,11 +4959,15 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const asset to_cpu_stake = core_sym::from_string("40.0000"); transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); + produce_block( fc::hours(30 * 24 + 12) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); + produce_block( fc::hours(30 * 24 + 12) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + rent) == From bfe33f3f0ad6bc4445d029537553874a2144a1fc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 29 Nov 2019 14:49:48 -0700 Subject: [PATCH 79/97] REX changes - distribute ramfee and namebids --- contracts/eosio.system/src/rex.cpp | 26 +++++++------- tests/eosio.system_tests.cpp | 54 +++++++++++++++++++----------- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 86b33c619..b33e597be 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -624,25 +624,25 @@ namespace eosiosystem { return; } + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; + const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first && _rexretpool.begin()->return_buckets.rbegin()->first <= ct; - int64_t new_bucket_overestimate = 0; + int64_t new_bucket_estimate = 0; if ( new_return_bucket ) { _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; - const uint32_t dt = rp.return_buckets.rbegin()->first.sec_since_epoch() - rp.last_update_time.sec_since_epoch(); - new_bucket_overestimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; + const uint32_t dt = ct.sec_since_epoch() - rp.return_buckets.rbegin()->first.sec_since_epoch(); + new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; }); } - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration - - new_bucket_overestimate; - const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; + int64_t change = change_estimate + new_bucket_estimate; - int64_t change = change_estimate; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { auto& return_buckets = rp.return_buckets; auto iter = return_buckets.begin(); @@ -651,7 +651,8 @@ namespace eosiosystem { ++next; const uint32_t overtime = ct.sec_since_epoch() - ( iter->first.sec_since_epoch() + rex_return_pool::total_duration ); const int64_t rate = iter->second; - const int64_t surplus = ( uint128_t(overtime) * rate ) / rex_return_pool::total_duration; + const int64_t surplus = ( uint128_t(overtime) * rate + rex_return_pool::total_duration - 1 ) + / rex_return_pool::total_duration; change -= surplus; rp.current_rate_of_increase -= rate; return_buckets.erase(iter); @@ -872,10 +873,7 @@ namespace eosiosystem { { #if CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX if ( rex_available() ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { - rp.total_unlent.amount += amount.amount; - rp.total_lendable.amount += amount.amount; - }); + add_to_rex_return_pool( amount ); // inline transfer to rex_account token::transfer_action transfer_act{ token_account, { from, active_permission } }; transfer_act.send( from, rex_account, amount, diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 538fd6098..c39a16c72 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -27,7 +27,8 @@ using namespace eosio_system; BOOST_AUTO_TEST_SUITE(eosio_system_tests) -bool within_one(int64_t a, int64_t b) { return std::abs(a - b) <= 1; } +bool within_error(int64_t a, int64_t b, int64_t err) { return std::abs(a - b) <= err; }; +bool within_one(int64_t a, int64_t b) { return within_error(a, b, 1); } BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { @@ -3991,8 +3992,8 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); auto expected_rex_fund = (init_balance + fee).get_amount(); auto actual_rex_fund = get_rex_fund(alice).get_amount(); - BOOST_REQUIRE_EQUAL( true, within_one( expected_rex_fund, actual_rex_fund ) ); - BOOST_REQUIRE( actual_rex_fund <= expected_rex_fund ); + BOOST_REQUIRE_EQUAL( true, within_error( expected_rex_fund, actual_rex_fund, 2 ) ); + BOOST_TEST_REQUIRE( actual_rex_fund <= expected_rex_fund ); // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); @@ -4422,12 +4423,20 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("0.3500") ); cur_rex_balance = get_balance( N(eosio.rex) ); + + produce_blocks( 1 ); + produce_block( fc::hours(30*24 + 12) ); + produce_blocks( 1 ); + + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); auto cur_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( cur_rex_balance, cur_rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["total_lent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, cur_rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); + BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_unlent"].as().get_amount() ) ); + BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["total_lent"].as().get_amount() ); + BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_lendable"].as().get_amount() ) ); + BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); // required for closing namebids cross_15_percent_threshold(); @@ -4449,8 +4458,14 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_unlent"].as() ); + produce_block( fc::hours(30*24 + 13) ); + produce_blocks( 1 ); + + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); + + BOOST_TEST_REQUIRE( within_error( cur_rex_balance.get_amount(), get_rex_pool()["total_lendable"].as().get_amount(), 4 ) ); + BOOST_TEST_REQUIRE( cur_rex_balance.get_amount() >= get_rex_pool()["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), get_rex_pool()["total_unlent"].as() ); } FC_LOG_AND_RETHROW() @@ -4884,7 +4899,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); - BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ) ); + BOOST_TEST_REQUIRE( within_error( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount(), 2 ) ); BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4899,7 +4914,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { +BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_test::tolerance(1e-8) ) try { cross_15_percent_threshold(); @@ -4945,11 +4960,12 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes produce_block( fc::days(31) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const auto curr_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( curr_rex_pool["total_lendable"].as(), init_rex_pool["total_lendable"].as() + rent ); + BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), + init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); - BOOST_REQUIRE_EQUAL( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); - BOOST_REQUIRE_EQUAL( purchase + rent, get_rex_vote_stake(alice) ); + BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); + BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == @@ -4959,18 +4975,18 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const asset to_cpu_stake = core_sym::from_string("40.0000"); transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 12) ); + produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); + BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 2 ) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 12) ); + produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); - BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + rent) == + BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 3 ) ); + BOOST_TEST_REQUIRE ( stake2votes(init_stake + get_rex_vote_stake(alice) ) == get_producer_info(producer_names[0])["total_votes"].as_double() ); } FC_LOG_AND_RETHROW() From 72e583657ba6023d7e77add569ea90219a5efae8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 1 Dec 2019 23:28:36 -0500 Subject: [PATCH 80/97] REX changes - more testing --- tests/eosio.system_tests.cpp | 105 +++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index c39a16c72..91f30683b 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5252,6 +5252,111 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { + + BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); + + const asset init_balance = core_sym::from_string("100000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance ); + + const asset payment = core_sym::from_string("100000.0000"); + { + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); + auto rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( payment, rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( payment, rex_pool["total_unlent"].as() ); + + BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); + } + + { + const asset fee = core_sym::from_string("30.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + auto rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + + produce_block( fc::hours(12) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + + uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600); + int64_t expected = payment.get_amount() + change; + + auto rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); + + produce_blocks( 1 ); + produce_block( fc::days(25) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + uint32_t t2 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600); + expected = payment.get_amount() + change; + + rex_pool = get_rex_pool(); + BOOST_TEST_REQUIRE( within_one( expected, rex_pool["total_lendable"].as().get_amount() ) ); + + produce_blocks( 1 ); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + + rex_pool = get_rex_pool(); + expected = payment.get_amount() + fee.get_amount(); + BOOST_TEST_REQUIRE( within_error( expected, rex_pool["total_lendable"].as().get_amount(), 2 ) ); + BOOST_TEST_REQUIRE( expected >= rex_pool["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_pool["total_lendable"].as(), + rex_pool["total_unlent"].as() ); + } + + produce_block( fc::hours(1) ); + + { + const asset init_lendable = get_rex_pool()["total_lendable"].as(); + const asset fee = core_sym::from_string("15.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + auto rex_return_pool = get_rex_return_pool(); + uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + produce_block( fc::hours(1) ); + BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + BOOST_REQUIRE_EQUAL( t0 + 3600, t1 ); + + produce_block( fc::hours(12) ); + BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); + produce_block( fc::hours(8) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + + produce_block( fc::days(30) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_TEST_REQUIRE( (init_lendable + fee + fee).get_amount() < get_rex_pool()["total_lendable"].as().get_amount() ); + + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_TEST_REQUIRE( within_error( init_lendable.get_amount() + 3 * fee.get_amount(), + get_rex_pool()["total_lendable"].as().get_amount(), 3 ) ); + } + +} FC_LOG_AND_RETHROW() + + BOOST_AUTO_TEST_CASE( setabi_bios ) try { fc::temp_directory tempdir; validating_tester t( tempdir, true ); From a9895b94b7b4b4519ffa7ad1fc80d2284ba29cef Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 2 Dec 2019 01:06:15 -0500 Subject: [PATCH 81/97] REX changes - unlent lower bound --- contracts/eosio.system/src/rex.cpp | 2 +- tests/eosio.system_tests.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index b33e597be..774f88162 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -733,7 +733,7 @@ namespace eosiosystem { asset stake_change( 0, core_symbol() ); bool success = false; - const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; + const int64_t unlent_lower_bound = rexitr->total_lent.amount / 10; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible if ( proceeds.amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 91f30683b..4e1bf9d58 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4088,8 +4088,8 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { setup_rex_accounts( accounts, init_balance ); const auto purchase1 = core_sym::from_string("50000.0000"); - const auto purchase2 = core_sym::from_string("235500.0000"); - const auto purchase3 = core_sym::from_string("234500.0000"); + const auto purchase2 = core_sym::from_string("105500.0000"); + const auto purchase3 = core_sym::from_string("104500.0000"); const auto init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); @@ -4108,12 +4108,12 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("20000.0000"), get_rex_pool()["total_rent"].as() ); for (uint8_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("20000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("12000.0000") ) ); } produce_block( fc::days(25) ); - const asset rent_payment = core_sym::from_string("40000.0000"); + const asset rent_payment = core_sym::from_string("46000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); produce_block( fc::days(4) ); @@ -4770,7 +4770,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("2000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("3000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 9 * rex_bucket_amount / 10, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); @@ -5043,11 +5043,11 @@ BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { const int64_t tot_lent = rex_pool["total_lent"].as().get_amount(); const int64_t tot_lendable = rex_pool["total_lendable"].as().get_amount(); double rex_per_eos = double(tot_rex) / double(tot_lendable); - int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.19 * tot_lent ); + int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.09 * tot_lent ); produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - sell_amount = rex_per_eos * ( tot_unlent - 0.2 * tot_lent ); + sell_amount = rex_per_eos * ( tot_unlent - 0.1 * tot_lent ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("no sellrex order is scheduled"), cancelrexorder( alice ) ); From 2fa92a36eda290b620950aded7e38f10a787eb53 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 2 Dec 2019 17:32:23 -0500 Subject: [PATCH 82/97] REX changes - use microseconds instead of seconds --- .../include/eosio.system/eosio.system.hpp | 13 ++++---- contracts/eosio.system/src/rex.cpp | 20 ++++++------ tests/eosio.system_tests.cpp | 31 ++++++++++--------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index a8e178313..2054a845a 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -64,6 +64,7 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_hour = 3600; static constexpr int64_t useconds_per_year = int64_t(seconds_per_year) * 1000'000ll; static constexpr int64_t useconds_per_day = int64_t(seconds_per_day) * 1000'000ll; + static constexpr int64_t useconds_per_hour = int64_t(seconds_per_hour) * 1000'000ll; static constexpr uint32_t blocks_per_day = 2 * seconds_per_day; // half seconds per day static constexpr int64_t min_activated_stake = 150'000'000'0000; @@ -339,13 +340,13 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { - uint8_t version = 0; - time_point_sec last_update_time; - int64_t current_rate_of_increase = 0; - std::map return_buckets; + uint8_t version = 0; + time_point last_update_time; + int64_t current_rate_of_increase = 0; + std::map return_buckets; - static constexpr uint32_t total_duration = 30 * seconds_per_day; - static constexpr uint8_t hours_per_bucket = 12; + static constexpr int64_t total_duration = 30 * useconds_per_day; + static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 774f88162..5bf02df16 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -618,16 +618,16 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - const time_point_sec ct = current_time_point(); + const time_point ct = current_time_point(); if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { return; } - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; - const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const uint64_t time_interval = ct.time_since_epoch().count() - _rexretpool.begin()->last_update_time.time_since_epoch().count(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const time_point time_threshold = ct - eosio::microseconds{rex_return_pool::total_duration}; const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first @@ -636,7 +636,7 @@ namespace eosiosystem { if ( new_return_bucket ) { _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; - const uint32_t dt = ct.sec_since_epoch() - rp.return_buckets.rbegin()->first.sec_since_epoch(); + const uint64_t dt = ct.time_since_epoch().count() - rp.return_buckets.rbegin()->first.time_since_epoch().count() ; new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; }); } @@ -649,7 +649,7 @@ namespace eosiosystem { while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; - const uint32_t overtime = ct.sec_since_epoch() - ( iter->first.sec_since_epoch() + rex_return_pool::total_duration ); + const uint64_t overtime = ct.time_since_epoch().count() - ( iter->first.time_since_epoch().count() + rex_return_pool::total_duration ); const int64_t rate = iter->second; const int64_t surplus = ( uint128_t(overtime) * rate + rex_return_pool::total_duration - 1 ) / rex_return_pool::total_duration; @@ -1017,9 +1017,9 @@ namespace eosiosystem { { update_rex_pool(); - const uint32_t cts = current_time_point().sec_since_epoch(); - const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; - const time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; + const int64_t cts = current_time_point().time_since_epoch().count(); + const int64_t bucket_interval = rex_return_pool::hours_per_bucket * useconds_per_hour; + const time_point effective_time{ eosio::microseconds{cts - cts % bucket_interval + bucket_interval} }; if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& rp ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 4e1bf9d58..e69fcc2ec 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4119,23 +4119,24 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { produce_block( fc::days(4) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - + const auto init_rex_pool = get_rex_pool(); const int64_t total_lendable = init_rex_pool["total_lendable"].as().get_amount(); const int64_t total_rex = init_rex_pool["total_rex"].as().get_amount(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * total_lendable ) / total_rex; - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol{SY(4,REX)} ) ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); + // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); + // BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ); + // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); @@ -4151,7 +4152,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); - // wait for 30 days minus 1 hour + // wait for a total of 30 days minus 1 hour produce_block( fc::hours(23) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); @@ -5277,15 +5278,15 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - produce_block( fc::hours(12) ); + produce_block( fc::hours(13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); - int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600); + int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); int64_t expected = payment.get_amount() + change; auto rex_pool = get_rex_pool(); @@ -5296,8 +5297,8 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t2 = rex_return_pool["last_update_time"].as().sec_since_epoch(); - change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600); + int64_t t2 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); expected = payment.get_amount() + change; rex_pool = get_rex_pool(); @@ -5325,13 +5326,13 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { const asset fee = core_sym::from_string("15.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); auto rex_return_pool = get_rex_return_pool(); - uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); produce_block( fc::hours(1) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); - BOOST_REQUIRE_EQUAL( t0 + 3600, t1 ); + int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + BOOST_REQUIRE_EQUAL( t1, t0 + 3600 * 1000000ll + 500000 ); produce_block( fc::hours(12) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); From 300e00722e0621578aec8e9037664556c4acda2e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 2 Dec 2019 18:12:17 -0500 Subject: [PATCH 83/97] REX changes - comments --- .../eosio.system/include/eosio.system/eosio.system.hpp | 7 ++++++- contracts/eosio.system/src/rex.cpp | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 2054a845a..72750ad0e 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -339,13 +339,18 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; + // `rex_return_pool` structure underlying the rex return pool table. A rex return pool table entry is defined by: + // - `version` defaulted to zero, + // - `last_update_time` the last time returns from renting, ram fees, and name bids were added to the rex pool, + // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, + // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; time_point last_update_time; int64_t current_rate_of_increase = 0; std::map return_buckets; - static constexpr int64_t total_duration = 30 * useconds_per_day; + static constexpr int64_t total_duration = 30 * useconds_per_day; static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 5bf02df16..4aeef7d5e 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -616,6 +616,9 @@ namespace eosiosystem { } + /** + * @brief Adds returns from the REX return pool to the REX pool + */ void system_contract::update_rex_pool() { const time_point ct = current_time_point(); @@ -1013,6 +1016,11 @@ namespace eosiosystem { return rex_received; } + /** + * @brief Adds an amount of core tokens to the REX return pool + * + * @param fee - amount to be added + */ void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); From 8d6760bc68793165ae47ba2191b4f0461fc3ed0e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 9 Dec 2019 16:16:12 -0500 Subject: [PATCH 84/97] REX changes - time interval between REX pool updates --- .../include/eosio.system/eosio.system.hpp | 6 ++++ contracts/eosio.system/src/rex.cpp | 11 ++++++- tests/eosio.system_tests.cpp | 32 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 72750ad0e..1bb0c27f3 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -343,14 +343,20 @@ namespace eosiosystem { // - `version` defaulted to zero, // - `last_update_time` the last time returns from renting, ram fees, and name bids were added to the rex pool, // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, + // - `cummulative_proceeds` bookkeeping variable that tracks fees added to rex pool up to current time, + // - `proceeds` bookkeeping variable that tracks fees added to rex return pool up to current time, // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; + time_point last_update_time; int64_t current_rate_of_increase = 0; + int64_t cummulative_proceeds = 0; + int64_t proceeds = 0; std::map return_buckets; static constexpr int64_t total_duration = 30 * useconds_per_day; + static constexpr int64_t dist_interval = 10 * 60 * 1000'000; static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 4aeef7d5e..d47017f40 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -623,7 +623,8 @@ namespace eosiosystem { { const time_point ct = current_time_point(); - if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { + if ( _rexretpool.begin() == _rexretpool.end() || + ct < _rexretpool.begin()->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { return; } @@ -672,6 +673,9 @@ namespace eosiosystem { pool.total_unlent.amount += change; pool.total_lendable = pool.total_unlent + pool.total_lent; }); + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.cummulative_proceeds += change; + }); } template @@ -1032,6 +1036,11 @@ namespace eosiosystem { if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& rp ) { rp.last_update_time = effective_time; + rp.proceeds += fee.amount; + }); + } else { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.proceeds += fee.amount; }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index e69fcc2ec..61355abc1 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5278,6 +5278,7 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); produce_block( fc::hours(13) ); @@ -5310,6 +5311,7 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); rex_pool = get_rex_pool(); expected = payment.get_amount() + fee.get_amount(); @@ -5331,11 +5333,15 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); BOOST_REQUIRE_EQUAL( t1, t0 + 3600 * 1000000ll + 500000 ); produce_block( fc::hours(12) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 2, rex_return_pool["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::hours(8) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); @@ -5351,10 +5357,36 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); BOOST_TEST_REQUIRE( within_error( init_lendable.get_amount() + 3 * fee.get_amount(), get_rex_pool()["total_lendable"].as().get_amount(), 3 ) ); } + { + const asset fee = core_sym::from_string("25.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + produce_block( fc::hours(13) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + auto rex_pool_0 = get_rex_pool(); + auto rex_return_pool_0 = get_rex_return_pool(); + produce_block( fc::minutes(9) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + auto rex_pool_1 = get_rex_pool(); + auto rex_return_pool_1 = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_update_time"].as().time_since_epoch().count(), + rex_return_pool_1["last_update_time"].as().time_since_epoch().count()); + BOOST_REQUIRE_EQUAL( rex_pool_0["total_lendable"].as(), + rex_pool_1["total_lendable"].as()); + produce_block( fc::minutes(1) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + auto rex_pool_2 = get_rex_pool(); + auto rex_return_pool_2 = get_rex_return_pool(); + BOOST_TEST_REQUIRE( rex_return_pool_1["last_update_time"].as().time_since_epoch().count() < + rex_return_pool_2["last_update_time"].as().time_since_epoch().count()); + BOOST_TEST_REQUIRE( rex_pool_1["total_lendable"].as().get_amount() < + rex_pool_2["total_lendable"].as().get_amount()); + } + } FC_LOG_AND_RETHROW() From a78e2eef9a1247358f6f9a33f100d5121b8c34af Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 9 Dec 2019 17:06:53 -0500 Subject: [PATCH 85/97] REX changes - larryk85's PR review --- contracts/eosio.system/src/rex.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index d47017f40..380cd8cc9 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -622,23 +622,24 @@ namespace eosiosystem { void system_contract::update_rex_pool() { const time_point ct = current_time_point(); + const auto ret_pool_elem = _rexretpool.begin(); - if ( _rexretpool.begin() == _rexretpool.end() || - ct < _rexretpool.begin()->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { + if ( ret_pool_elem == _rexretpool.end() || + ct < ret_pool_elem->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { return; } - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const uint64_t time_interval = ct.time_since_epoch().count() - _rexretpool.begin()->last_update_time.time_since_epoch().count(); + const int64_t current_rate = ret_pool_elem->current_rate_of_increase; + const uint64_t time_interval = ct.time_since_epoch().count() - ret_pool_elem->last_update_time.time_since_epoch().count(); const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; const time_point time_threshold = ct - eosio::microseconds{rex_return_pool::total_duration}; - const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() - && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first - && _rexretpool.begin()->return_buckets.rbegin()->first <= ct; + const bool new_return_bucket = !ret_pool_elem->return_buckets.empty() + && ret_pool_elem->last_update_time <= ret_pool_elem->return_buckets.rbegin()->first + && ret_pool_elem->return_buckets.rbegin()->first <= ct; int64_t new_bucket_estimate = 0; if ( new_return_bucket ) { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; const uint64_t dt = ct.time_since_epoch().count() - rp.return_buckets.rbegin()->first.time_since_epoch().count() ; new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; @@ -647,7 +648,7 @@ namespace eosiosystem { int64_t change = change_estimate + new_bucket_estimate; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { auto& return_buckets = rp.return_buckets; auto iter = return_buckets.begin(); while ( iter != return_buckets.end() && iter->first <= time_threshold ) { @@ -673,7 +674,7 @@ namespace eosiosystem { pool.total_unlent.amount += change; pool.total_lendable = pool.total_unlent + pool.total_lent; }); - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { rp.cummulative_proceeds += change; }); } From bed60a901f75b7b1c237cd5db99c5bc94268d9bb Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 10 Dec 2019 18:02:50 -0500 Subject: [PATCH 86/97] REX changes - arhag's PR review --- .../include/eosio.system/eosio.system.hpp | 67 ++++---- contracts/eosio.system/src/eosio.system.cpp | 1 + contracts/eosio.system/src/rex.cpp | 147 +++++++++++------- 3 files changed, 130 insertions(+), 85 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 1bb0c27f3..037b3a9d8 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -345,25 +345,33 @@ namespace eosiosystem { // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, // - `cummulative_proceeds` bookkeeping variable that tracks fees added to rex pool up to current time, // - `proceeds` bookkeeping variable that tracks fees added to rex return pool up to current time, - // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective + // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { - uint8_t version = 0; - - time_point last_update_time; - int64_t current_rate_of_increase = 0; - int64_t cummulative_proceeds = 0; - int64_t proceeds = 0; - std::map return_buckets; - - static constexpr int64_t total_duration = 30 * useconds_per_day; - static constexpr int64_t dist_interval = 10 * 60 * 1000'000; - static constexpr uint8_t hours_per_bucket = 12; + uint8_t version = 0; + time_point_sec last_dist_time; + time_point_sec pending_bucket_time = time_point_sec::maximum(); + time_point_sec oldest_bucket_time = time_point_sec::min(); + int64_t pending_bucket_proceeds = 0; + int64_t current_rate_of_increase = 0; + + static constexpr int32_t total_intervals = 30 * 144; // 30 days + static constexpr int32_t dist_interval = 10 * 60; // 10 minutes + static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } }; typedef eosio::multi_index< "rexretpool"_n, rex_return_pool > rex_return_pool_table; + struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_buckets { + uint8_t version = 0; + std::map return_buckets; + + uint64_t primary_key()const { return 0; } + }; + + typedef eosio::multi_index< "retbuckets"_n, rex_return_buckets > rex_return_buckets_table; + // `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: // - `version` defaulted to zero, // - `owner` the owner of the rex fund, @@ -461,23 +469,24 @@ namespace eosiosystem { class [[eosio::contract("eosio.system")]] system_contract : public native { private: - voters_table _voters; - producers_table _producers; - producers_table2 _producers2; - global_state_singleton _global; - global_state2_singleton _global2; - global_state3_singleton _global3; - global_state4_singleton _global4; - eosio_global_state _gstate; - eosio_global_state2 _gstate2; - eosio_global_state3 _gstate3; - eosio_global_state4 _gstate4; - rammarket _rammarket; - rex_pool_table _rexpool; - rex_return_pool_table _rexretpool; - rex_fund_table _rexfunds; - rex_balance_table _rexbalance; - rex_order_table _rexorders; + voters_table _voters; + producers_table _producers; + producers_table2 _producers2; + global_state_singleton _global; + global_state2_singleton _global2; + global_state3_singleton _global3; + global_state4_singleton _global4; + eosio_global_state _gstate; + eosio_global_state2 _gstate2; + eosio_global_state3 _gstate3; + eosio_global_state4 _gstate4; + rammarket _rammarket; + rex_pool_table _rexpool; + rex_return_pool_table _rexretpool; + rex_return_buckets_table _rexretbuckets; + rex_fund_table _rexfunds; + rex_balance_table _rexbalance; + rex_order_table _rexorders; public: static constexpr eosio::name active_permission{"active"_n}; diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index a6af9e0d0..202210c7d 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -27,6 +27,7 @@ namespace eosiosystem { _rammarket(get_self(), get_self().value), _rexpool(get_self(), get_self().value), _rexretpool(get_self(), get_self().value), + _rexretbuckets(get_self(), get_self().value), _rexfunds(get_self(), get_self().value), _rexbalance(get_self(), get_self().value), _rexorders(get_self(), get_self().value) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 380cd8cc9..663336d2f 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -621,62 +621,92 @@ namespace eosiosystem { */ void system_contract::update_rex_pool() { - const time_point ct = current_time_point(); - const auto ret_pool_elem = _rexretpool.begin(); + auto get_elapsed_intervals = [&](const time_point_sec& t1, const time_point_sec& t0) -> uint32_t { + return (t1.sec_since_epoch() - t0.sec_since_epoch()) / rex_return_pool::dist_interval; + }; + + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + const time_point_sec effective_time{cts - cts % rex_return_pool::dist_interval}; - if ( ret_pool_elem == _rexretpool.end() || - ct < ret_pool_elem->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { + const auto ret_pool_elem = _rexretpool.begin(); + const auto ret_buckets_elem = _rexretbuckets.begin(); + + if ( ret_pool_elem == _rexretpool.end() || effective_time <= ret_pool_elem->last_dist_time ) { return; } - const int64_t current_rate = ret_pool_elem->current_rate_of_increase; - const uint64_t time_interval = ct.time_since_epoch().count() - ret_pool_elem->last_update_time.time_since_epoch().count(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; - const time_point time_threshold = ct - eosio::microseconds{rex_return_pool::total_duration}; + const int64_t current_rate = ret_pool_elem->current_rate_of_increase; + const uint32_t elapsed_intervals = get_elapsed_intervals(effective_time, ret_pool_elem->last_dist_time); + int64_t change_estimate = current_rate * elapsed_intervals; - const bool new_return_bucket = !ret_pool_elem->return_buckets.empty() - && ret_pool_elem->last_update_time <= ret_pool_elem->return_buckets.rbegin()->first - && ret_pool_elem->return_buckets.rbegin()->first <= ct; - int64_t new_bucket_estimate = 0; - if ( new_return_bucket ) { + { + const bool new_return_bucket = ret_pool_elem->pending_bucket_time < effective_time; + int64_t new_bucket_rate = 0; + time_point_sec new_bucket_time{0}; _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; - const uint64_t dt = ct.time_since_epoch().count() - rp.return_buckets.rbegin()->first.time_since_epoch().count() ; - new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; + if ( new_return_bucket ) { + int64_t remainder = rp.pending_bucket_proceeds % rex_return_pool::total_intervals; + new_bucket_rate = ( rp.pending_bucket_proceeds - remainder ) / rex_return_pool::total_intervals; + new_bucket_time = rp.pending_bucket_time; + rp.current_rate_of_increase += new_bucket_rate; + change_estimate += remainder + new_bucket_rate * get_elapsed_intervals( effective_time, rp.pending_bucket_time ); + rp.pending_bucket_proceeds = 0; + rp.pending_bucket_time = time_point_sec::maximum(); + if ( new_bucket_time < rp.oldest_bucket_time ) { + rp.oldest_bucket_time = new_bucket_time; + } + } + rp.last_dist_time = effective_time; }); + + if ( new_return_bucket ) { + _rexretbuckets.modify( ret_buckets_elem, same_payer, [&]( auto& rb ) { + rb.return_buckets[new_bucket_time] = new_bucket_rate; + }); + } } - int64_t change = change_estimate + new_bucket_estimate; + const time_point_sec time_threshold = effective_time - eosio::seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval); + if ( ret_pool_elem->oldest_bucket_time <= time_threshold ) { + int64_t expired_rate = 0; + int64_t surplus = 0; + _rexretbuckets.modify( ret_buckets_elem, same_payer, [&]( auto& rb ) { + auto& return_buckets = rb.return_buckets; + auto iter = return_buckets.begin(); + while ( iter != return_buckets.end() && iter->first <= time_threshold ) { + auto next = iter; + ++next; + const uint32_t overtime = get_elapsed_intervals( effective_time, iter->first + rex_return_pool::total_intervals ); + surplus += iter->second * overtime; + expired_rate += iter->second; + return_buckets.erase(iter); + } + }); - _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - auto& return_buckets = rp.return_buckets; - auto iter = return_buckets.begin(); - while ( iter != return_buckets.end() && iter->first <= time_threshold ) { - auto next = iter; - ++next; - const uint64_t overtime = ct.time_since_epoch().count() - ( iter->first.time_since_epoch().count() + rex_return_pool::total_duration ); - const int64_t rate = iter->second; - const int64_t surplus = ( uint128_t(overtime) * rate + rex_return_pool::total_duration - 1 ) - / rex_return_pool::total_duration; - change -= surplus; - rp.current_rate_of_increase -= rate; - return_buckets.erase(iter); - iter = next; - } - rp.last_update_time = ct; - }); + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { + if ( !ret_buckets_elem->return_buckets.empty() ) { + rp.oldest_bucket_time = ret_buckets_elem->return_buckets.begin()->first; + } else { + rp.oldest_bucket_time = time_point_sec::min(); + } - if ( change <= 0 ) { - return; + if ( expired_rate > 0) { + rp.current_rate_of_increase -= expired_rate; + } + }); + + if ( surplus > 0 ) { + change_estimate -= surplus; + } } - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { - pool.total_unlent.amount += change; - pool.total_lendable = pool.total_unlent + pool.total_lent; - }); - _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - rp.cummulative_proceeds += change; - }); + if ( change_estimate > 0 ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { + pool.total_unlent.amount += change_estimate; + pool.total_lendable = pool.total_unlent + pool.total_lent; + }); + } } template @@ -1029,25 +1059,30 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); + if ( fee.amount <= 0) { + return; + } - const int64_t cts = current_time_point().time_since_epoch().count(); - const int64_t bucket_interval = rex_return_pool::hours_per_bucket * useconds_per_hour; - const time_point effective_time{ eosio::microseconds{cts - cts % bucket_interval + bucket_interval} }; - - if ( _rexretpool.begin() == _rexretpool.end() ) { + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; + const time_point_sec effective_time{cts - cts % bucket_interval + bucket_interval}; + const auto return_pool_elem = _rexretpool.begin(); + if ( return_pool_elem == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& rp ) { - rp.last_update_time = effective_time; - rp.proceeds += fee.amount; + rp.last_dist_time = effective_time; + rp.pending_bucket_proceeds = fee.amount; + rp.pending_bucket_time = effective_time; }); + _rexretbuckets.emplace( get_self(), [&]( auto& rb ) { } ); } else { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { - rp.proceeds += fee.amount; + _rexretpool.modify( return_pool_elem, same_payer, [&]( auto& rp ) { + rp.pending_bucket_proceeds += fee.amount; + if ( rp.pending_bucket_time == time_point_sec::maximum() ) { + rp.pending_bucket_time = effective_time; + } }); } - - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { - rp.return_buckets[effective_time] += fee.amount; - }); } /** From e1dfd528bbfa59afb39fc7c77b0967024170dde7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 00:47:04 -0500 Subject: [PATCH 87/97] REX changes - tests --- contracts/eosio.system/src/rex.cpp | 18 ++--- tests/eosio.system_tester.hpp | 21 ++++++ tests/eosio.system_tests.cpp | 105 +++++++++++++++++------------ 3 files changed, 94 insertions(+), 50 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 663336d2f..c775a25b7 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -6,6 +6,7 @@ namespace eosiosystem { using eosio::current_time_point; using eosio::token; + using eosio::seconds; void system_contract::deposit( const name& owner, const asset& amount ) { @@ -621,8 +622,8 @@ namespace eosiosystem { */ void system_contract::update_rex_pool() { - auto get_elapsed_intervals = [&](const time_point_sec& t1, const time_point_sec& t0) -> uint32_t { - return (t1.sec_since_epoch() - t0.sec_since_epoch()) / rex_return_pool::dist_interval; + auto get_elapsed_intervals = [&]( const time_point_sec& t1, const time_point_sec& t0 ) -> uint32_t { + return ( t1.sec_since_epoch() - t0.sec_since_epoch() ) / rex_return_pool::dist_interval; }; const time_point_sec ct = current_time_point(); @@ -637,13 +638,13 @@ namespace eosiosystem { } const int64_t current_rate = ret_pool_elem->current_rate_of_increase; - const uint32_t elapsed_intervals = get_elapsed_intervals(effective_time, ret_pool_elem->last_dist_time); + const uint32_t elapsed_intervals = get_elapsed_intervals( effective_time, ret_pool_elem->last_dist_time ); int64_t change_estimate = current_rate * elapsed_intervals; { const bool new_return_bucket = ret_pool_elem->pending_bucket_time < effective_time; int64_t new_bucket_rate = 0; - time_point_sec new_bucket_time{0}; + time_point_sec new_bucket_time = time_point_sec::min(); _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { if ( new_return_bucket ) { int64_t remainder = rp.pending_bucket_proceeds % rex_return_pool::total_intervals; @@ -667,7 +668,7 @@ namespace eosiosystem { } } - const time_point_sec time_threshold = effective_time - eosio::seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval); + const time_point_sec time_threshold = effective_time - seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval); if ( ret_pool_elem->oldest_bucket_time <= time_threshold ) { int64_t expired_rate = 0; int64_t surplus = 0; @@ -677,10 +678,12 @@ namespace eosiosystem { while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; - const uint32_t overtime = get_elapsed_intervals( effective_time, iter->first + rex_return_pool::total_intervals ); + const uint32_t overtime = get_elapsed_intervals( effective_time, + iter->first + seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval) ); surplus += iter->second * overtime; expired_rate += iter->second; return_buckets.erase(iter); + iter = next; } }); @@ -690,7 +693,6 @@ namespace eosiosystem { } else { rp.oldest_bucket_time = time_point_sec::min(); } - if ( expired_rate > 0) { rp.current_rate_of_increase -= expired_rate; } @@ -1059,7 +1061,7 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - if ( fee.amount <= 0) { + if ( fee.amount <= 0 ) { return; } diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index a4795c03b..baf82bfda 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -687,6 +687,27 @@ class eosio_system_tester : public TESTER { return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer_max_time ); } + fc::variant get_rex_return_buckets() const { + vector data; + const auto& db = control->db(); + namespace chain = eosio::chain; + const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(retbuckets) ) ); + if ( !t_id ) { + return fc::variant(); + } + + const auto& idx = db.get_index(); + + auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); + if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { + return fc::variant(); + } + + data.resize( itr->value.size() ); + memcpy( data.data(), itr->value.data(), data.size() ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_buckets", data, abi_serializer_max_time ); + } + void setup_rex_accounts( const std::vector& accounts, const asset& init_balance, const asset& net = core_sym::from_string("80.0000"), diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 61355abc1..d09ee6bf4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3984,7 +3984,8 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + int64_t rate = fee.get_amount() / (30 * 144); + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(10) ); // alice is finally able to sellrex, she gains the fee paid by bob @@ -3992,8 +3993,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); auto expected_rex_fund = (init_balance + fee).get_amount(); auto actual_rex_fund = get_rex_fund(alice).get_amount(); - BOOST_REQUIRE_EQUAL( true, within_error( expected_rex_fund, actual_rex_fund, 2 ) ); - BOOST_TEST_REQUIRE( actual_rex_fund <= expected_rex_fund ); + BOOST_REQUIRE_EQUAL( expected_rex_fund, actual_rex_fund ); // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); @@ -4463,10 +4463,9 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - - BOOST_TEST_REQUIRE( within_error( cur_rex_balance.get_amount(), get_rex_pool()["total_lendable"].as().get_amount(), 4 ) ); - BOOST_TEST_REQUIRE( cur_rex_balance.get_amount() >= get_rex_pool()["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), get_rex_pool()["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), + get_rex_pool()["total_unlent"].as() ); } FC_LOG_AND_RETHROW() @@ -4899,8 +4898,8 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_rex.get_amount()) * total_lendable ) / total_rex; const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); - BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); - BOOST_TEST_REQUIRE( within_error( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount(), 2 ) ); + BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance(alice) + rex_sell_amount ); + BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake(alice).get_amount() ); BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4979,14 +4978,14 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 2 ) ); + BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 3 ) ); + BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + get_rex_vote_stake(alice) ) == get_producer_info(producer_names[0])["total_votes"].as_double() ); @@ -5255,6 +5254,8 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { + constexpr uint32_t total_intervals = 30 * 144; + constexpr uint32_t dist_interval = 10 * 60; BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); const asset init_balance = core_sym::from_string("100000.0000"); @@ -5278,16 +5279,17 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); - int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + int32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); produce_block( fc::hours(13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + int64_t rate = fee.get_amount() / total_intervals; + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); + int32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + int64_t change = rate * ((t1-t0) / dist_interval) + fee.get_amount() % total_intervals; int64_t expected = payment.get_amount() + change; auto rex_pool = get_rex_pool(); @@ -5297,13 +5299,14 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { produce_block( fc::days(25) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); - int64_t t2 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); + int64_t t2 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + change = rate * ((t2-t0) / dist_interval) + fee.get_amount() % total_intervals; expected = payment.get_amount() + change; rex_pool = get_rex_pool(); - BOOST_TEST_REQUIRE( within_one( expected, rex_pool["total_lendable"].as().get_amount() ) ); + BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); produce_blocks( 1 ); produce_block( fc::days(5) ); @@ -5311,12 +5314,11 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); rex_pool = get_rex_pool(); expected = payment.get_amount() + fee.get_amount(); - BOOST_TEST_REQUIRE( within_error( expected, rex_pool["total_lendable"].as().get_amount(), 2 ) ); - BOOST_TEST_REQUIRE( expected >= rex_pool["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_lendable"].as(), rex_pool["total_unlent"].as() ); } @@ -5328,38 +5330,39 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { const asset fee = core_sym::from_string("15.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); auto rex_return_pool = get_rex_return_pool(); - int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + uint32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); produce_block( fc::hours(1) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); - int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - BOOST_REQUIRE_EQUAL( t1, t0 + 3600 * 1000000ll + 500000 ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + uint32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + BOOST_REQUIRE_EQUAL( t1, t0 + 6 * dist_interval ); produce_block( fc::hours(12) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 2, rex_return_pool["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); + int64_t rate = 2 * fee.get_amount() / total_intervals; + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::hours(8) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(30) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( fee.get_amount() / total_intervals, rex_return_pool["current_rate_of_increase"].as() ); BOOST_TEST_REQUIRE( (init_lendable + fee + fee).get_amount() < get_rex_pool()["total_lendable"].as().get_amount() ); produce_block( fc::days(1) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); - BOOST_TEST_REQUIRE( within_error( init_lendable.get_amount() + 3 * fee.get_amount(), - get_rex_pool()["total_lendable"].as().get_amount(), 3 ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( init_lendable.get_amount() + 3 * fee.get_amount(), + get_rex_pool()["total_lendable"].as().get_amount() ); } { @@ -5369,24 +5372,42 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); auto rex_pool_0 = get_rex_pool(); auto rex_return_pool_0 = get_rex_return_pool(); - produce_block( fc::minutes(9) ); + produce_block( fc::minutes(2) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); auto rex_pool_1 = get_rex_pool(); auto rex_return_pool_1 = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_update_time"].as().time_since_epoch().count(), - rex_return_pool_1["last_update_time"].as().time_since_epoch().count()); + BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_dist_time"].as().sec_since_epoch(), + rex_return_pool_1["last_dist_time"].as().sec_since_epoch() ); BOOST_REQUIRE_EQUAL( rex_pool_0["total_lendable"].as(), - rex_pool_1["total_lendable"].as()); - produce_block( fc::minutes(1) ); + rex_pool_1["total_lendable"].as() ); + produce_block( fc::minutes(9) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); auto rex_pool_2 = get_rex_pool(); auto rex_return_pool_2 = get_rex_return_pool(); - BOOST_TEST_REQUIRE( rex_return_pool_1["last_update_time"].as().time_since_epoch().count() < - rex_return_pool_2["last_update_time"].as().time_since_epoch().count()); + BOOST_TEST_REQUIRE( rex_return_pool_1["last_dist_time"].as().sec_since_epoch() < + rex_return_pool_2["last_dist_time"].as().sec_since_epoch() ); BOOST_TEST_REQUIRE( rex_pool_1["total_lendable"].as().get_amount() < - rex_pool_2["total_lendable"].as().get_amount()); + rex_pool_2["total_lendable"].as().get_amount() ); + produce_block( fc::days(31) ); + produce_blocks( 1 ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_pool()["current_rate_of_increase"].as() ); } + { + const asset fee = core_sym::from_string("30.0000"); + for ( uint8_t i = 0; i < 5; ++i ) { + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + produce_block( fc::days(1) ); + } + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + BOOST_REQUIRE_EQUAL( 5, get_rex_return_buckets()["return_buckets"].get_array().size() ); + produce_block( fc::days(30) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + } + } FC_LOG_AND_RETHROW() From c7a62d725c2b5597785d389615e831e2a1eb0e79 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 11:16:53 -0500 Subject: [PATCH 88/97] REX changes - updated comments --- .../include/eosio.system/eosio.system.hpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 037b3a9d8..3886d4a53 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -341,11 +341,11 @@ namespace eosiosystem { // `rex_return_pool` structure underlying the rex return pool table. A rex return pool table entry is defined by: // - `version` defaulted to zero, - // - `last_update_time` the last time returns from renting, ram fees, and name bids were added to the rex pool, - // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, - // - `cummulative_proceeds` bookkeeping variable that tracks fees added to rex pool up to current time, - // - `proceeds` bookkeeping variable that tracks fees added to rex return pool up to current time, - // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective + // - `last_dist_time` the last time proceeds from renting, ram fees, and name bids were added to the rex pool, + // - `pending_bucket_time` timestamp of the pending 12-hour return bucket, + // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, + // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, + // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; time_point_sec last_dist_time; @@ -354,15 +354,18 @@ namespace eosiosystem { int64_t pending_bucket_proceeds = 0; int64_t current_rate_of_increase = 0; - static constexpr int32_t total_intervals = 30 * 144; // 30 days - static constexpr int32_t dist_interval = 10 * 60; // 10 minutes - static constexpr uint8_t hours_per_bucket = 12; + static constexpr uint32_t total_intervals = 30 * 144; // 30 days + static constexpr uint32_t dist_interval = 10 * 60; // 10 minutes + static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } }; typedef eosio::multi_index< "rexretpool"_n, rex_return_pool > rex_return_pool_table; + // `rex_return_buckets` structure underlying the rex return buckets table. A rex return buckets table is defined by: + // - `version` defaulted to zero, + // - `return_buckets` buckets of proceeds accumulated in 12-hour intervals struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_buckets { uint8_t version = 0; std::map return_buckets; From d9ccc2268dcca67489936de58caa78a0ee4b167d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 15:20:49 -0500 Subject: [PATCH 89/97] REX changes - additional checks --- .../include/eosio.system/eosio.system.hpp | 5 ++++- contracts/eosio.system/src/rex.cpp | 20 ++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 3886d4a53..fb7e8cdb1 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -345,7 +345,8 @@ namespace eosiosystem { // - `pending_bucket_time` timestamp of the pending 12-hour return bucket, // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, - // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool + // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool, + // - `proceeds` the maximum amount of proceeds that can be added to the rex pool at any given time struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; time_point_sec last_dist_time; @@ -353,10 +354,12 @@ namespace eosiosystem { time_point_sec oldest_bucket_time = time_point_sec::min(); int64_t pending_bucket_proceeds = 0; int64_t current_rate_of_increase = 0; + int64_t proceeds = 0; static constexpr uint32_t total_intervals = 30 * 144; // 30 days static constexpr uint32_t dist_interval = 10 * 60; // 10 minutes static constexpr uint8_t hours_per_bucket = 12; + static_assert( total_intervals * dist_interval == 30 * seconds_per_day ); uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index c775a25b7..8e9d881f3 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -642,7 +642,7 @@ namespace eosiosystem { int64_t change_estimate = current_rate * elapsed_intervals; { - const bool new_return_bucket = ret_pool_elem->pending_bucket_time < effective_time; + const bool new_return_bucket = ret_pool_elem->pending_bucket_time <= effective_time; int64_t new_bucket_rate = 0; time_point_sec new_bucket_time = time_point_sec::min(); _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { @@ -658,6 +658,7 @@ namespace eosiosystem { rp.oldest_bucket_time = new_bucket_time; } } + rp.proceeds -= change_estimate; rp.last_dist_time = effective_time; }); @@ -696,11 +697,18 @@ namespace eosiosystem { if ( expired_rate > 0) { rp.current_rate_of_increase -= expired_rate; } + if ( surplus > 0 ) { + change_estimate -= surplus; + rp.proceeds += surplus; + } }); + } - if ( surplus > 0 ) { - change_estimate -= surplus; - } + if ( change_estimate > 0 && ret_pool_elem->proceeds < 0 ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { + change_estimate += rp.proceeds; + rp.proceeds = 0; + }); } if ( change_estimate > 0 ) { @@ -1074,12 +1082,14 @@ namespace eosiosystem { _rexretpool.emplace( get_self(), [&]( auto& rp ) { rp.last_dist_time = effective_time; rp.pending_bucket_proceeds = fee.amount; - rp.pending_bucket_time = effective_time; + rp.pending_bucket_time = effective_time; + rp.proceeds = fee.amount; }); _rexretbuckets.emplace( get_self(), [&]( auto& rb ) { } ); } else { _rexretpool.modify( return_pool_elem, same_payer, [&]( auto& rp ) { rp.pending_bucket_proceeds += fee.amount; + rp.proceeds += fee.amount; if ( rp.pending_bucket_time == time_point_sec::maximum() ) { rp.pending_bucket_time = effective_time; } From 8759a624c817516a51b4dbae7f3f95e592818d38 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 18:59:46 -0500 Subject: [PATCH 90/97] REX changes - fix build issues --- tests/eosio.system_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d09ee6bf4..4a15fc127 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4871,9 +4871,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, { producer_names.begin(), producer_names.begin() + 20 } ) ); + vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 20 ) ) ); BOOST_REQUIRE_EQUAL( success(), - vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); + vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4907,7 +4907,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to produce_block( fc::days(31) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names[0], producer_names[4] ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); @@ -4963,7 +4963,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == From e3d637bc03c2ceef1d2a7e701f07a88ffa338202 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 19:08:50 -0500 Subject: [PATCH 91/97] REX changes - fix build issues --- tests/eosio.system_tests.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 4a15fc127..120cfb050 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4871,9 +4871,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 20 ) ) ); + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4907,7 +4907,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to produce_block( fc::days(31) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names[0], producer_names[4] ) ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names[0], producer_names[4]) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); @@ -4949,7 +4949,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( purchase.get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); @@ -4963,7 +4963,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == From 705462c6060a378d816135da08af7814b41c3270 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 19:38:54 -0500 Subject: [PATCH 92/97] REX changes - tests --- tests/eosio.system_tests.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 120cfb050..d247085c3 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4128,9 +4128,6 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol{SY(4,REX)} ) ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); - // BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ); - // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); @@ -4881,7 +4878,11 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to == get_producer_info(producer_names[20])["total_votes"].as() ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); + + produce_blocks( 1 ); produce_block( fc::days(10) ); + produce_blocks( 1 ); + BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); @@ -4889,7 +4890,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); + produce_blocks( 1 ); produce_block( fc::hours(19 * 24 + 23) ); + produce_blocks( 1 ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); @@ -4903,8 +4907,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); - + + produce_blocks( 1 ); produce_block( fc::days(31) ); + produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names[0], producer_names[4]) ) ); From 3647ed9e93811a7663d605acae3bdfe1b8267500 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 19:47:03 -0500 Subject: [PATCH 93/97] REX changes - tests --- tests/eosio.system_tests.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d247085c3..f076a2aa8 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4913,7 +4913,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names[0], producer_names[4]) ) ); + std::vector two_producers; + two_producers.push_back( producer_names[0] ); + two_producers.push_back( producer_names[4] ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, two_producers ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); From b3cf026153d107776c1018e839440e65d2ff57d1 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 12 Dec 2019 10:34:37 -0500 Subject: [PATCH 94/97] REX changes - code cleaning --- tests/eosio.system_tests.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index f076a2aa8..e06bc5bb2 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4878,11 +4878,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to == get_producer_info(producer_names[20])["total_votes"].as() ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - - produce_blocks( 1 ); produce_block( fc::days(10) ); - produce_blocks( 1 ); - BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); @@ -4890,10 +4886,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); - produce_blocks( 1 ); produce_block( fc::hours(19 * 24 + 23) ); - produce_blocks( 1 ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); @@ -4907,16 +4900,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); - - produce_blocks( 1 ); produce_block( fc::days(31) ); - produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - std::vector two_producers; - two_producers.push_back( producer_names[0] ); - two_producers.push_back( producer_names[4] ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, two_producers ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); From 282534d2a1855837c302ba0fef38f1dc788a6133 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 13 Dec 2019 14:41:28 -0500 Subject: [PATCH 95/97] REX changes - arhag's PR review --- tests/eosio.system_tests.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index e06bc5bb2..c2eab2ccc 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5270,13 +5270,18 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { } { - const asset fee = core_sym::from_string("30.0000"); + const asset fee = core_sym::from_string("30.0000"); + const uint32_t bucket_interval_sec = fc::hours(12).to_seconds(); + const uint32_t current_time_sec = control->pending_block_time().sec_since_epoch(); + const time_point_sec expected_pending_bucket_time{current_time_sec - current_time_sec % bucket_interval_sec + bucket_interval_sec}; BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - int32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + BOOST_REQUIRE_EQUAL( expected_pending_bucket_time.sec_since_epoch(), + rex_return_pool["pending_bucket_time"].as().sec_since_epoch() ); + int32_t t0 = rex_return_pool["pending_bucket_time"].as().sec_since_epoch(); produce_block( fc::hours(13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); From 5905369fd5a0386c9d3b66edb245f8ec6f458ed4 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Dec 2019 10:25:21 -0500 Subject: [PATCH 96/97] bump version to v1.9.0-rc4 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 944d08c2b..fbf5e4f36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc3) +set(VERSION_SUFFIX rc4) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 4649af9d1..a33f70323 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc3 +## Version : 1.9.0-rc4 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. From 5eb391bc989a0914a10f0858cb0e337283b247fa Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 10 Jan 2020 10:26:38 -0500 Subject: [PATCH 97/97] bump version to v1.9.0 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fbf5e4f36..08c995ed9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc4) +#set(VERSION_SUFFIX rc4) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index a33f70323..46070ba11 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc4 +## Version : 1.9.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts.