-
Notifications
You must be signed in to change notification settings - Fork 263
Document of the Genesis Contract #3517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
eanzhao
wants to merge
2
commits into
docs
Choose a base branch
from
docs-genesis-contract
base: docs
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
232 changes: 232 additions & 0 deletions
232
docs-sphinx/reference/smart-contract/genesis-contract.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,232 @@ | ||
| # Genesis Contract | ||
|
|
||
| ## Overview | ||
|
|
||
| Genesis Contract, also known as the Zero Contract, is mainly used to deploy and maintain smart contracts running on the aelf blockchain. | ||
|
|
||
| This contract will be deployed first when aelf blockchain launched so that it can be used to deploy other smart contracts. | ||
|
|
||
| To achieve this purpose, the Genesis Contract implements the following methods defined in [acs0](https://docs.aelf.io/en/latest/reference/acs/acs0.html): | ||
|
|
||
| ```protobuf | ||
| service ACS0 { | ||
| // Deploy a system smart contract on chain and return the address of the system contract deployed. | ||
| rpc DeploySystemSmartContract (SystemContractDeploymentInput) returns (aelf.Address) { | ||
| } | ||
|
|
||
| // Deploy a smart contract on chain and return the address of the contract deployed. | ||
| rpc DeploySmartContract (ContractDeploymentInput) returns (aelf.Address) { | ||
| } | ||
|
|
||
| // Update a smart contract on chain. | ||
| rpc UpdateSmartContract (ContractUpdateInput) returns (aelf.Address) { | ||
| } | ||
|
|
||
| // and others. | ||
| // ... | ||
| } | ||
| ``` | ||
|
|
||
| Therefore, developers can deploy (and update) their own smart contracts by interacting with the Genesis Contract. | ||
|
|
||
| In this article, we will discuss: | ||
|
|
||
| - States related to smart contracts | ||
| - Implementation of deploy and update contracts | ||
| - How the contract will be loaded to the smart contract execution environment | ||
| - The current process of deploying and updating aelf smart contracts | ||
| - Other details of the Genesis Contract | ||
|
|
||
| ## States related to smart contracts | ||
|
|
||
arg-foo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| On aelf, each contract has the ability to read and write the general ledgers through a State | ||
| defined by a protobuf message. | ||
|
|
||
| The Genesis Contract uses `SmartContractRegistration` and `ContractInfo` states | ||
| to store contract information in the general ledger of the aelf blockchain. | ||
|
|
||
| The data structure of `SmartContractRegistration` is defined in `aelf/core.proto`: | ||
|
|
||
| ```C# | ||
| message SmartContractRegistration { | ||
| // The category of contract code(0: C#). | ||
| sint32 category = 1; | ||
| // The byte array of the contract code. | ||
| bytes code = 2; | ||
| // The hash of the contract code. | ||
| Hash code_hash = 3; | ||
| // Whether it is a system contract. | ||
| bool is_system_contract = 4; | ||
| // The version of the current contract. | ||
| int32 version = 5; | ||
| // The version of the contract. | ||
| string contract_version = 6; | ||
| // The address of the current contract. | ||
| Address contract_address = 7; | ||
| // Indicates if the contract is the user contract. | ||
| bool is_user_contract = 8; | ||
| } | ||
| ``` | ||
| Smart Contract code is stored in the `code` field. | ||
|
|
||
| We use the `State.SmartContractRegistrations` to access stored `SmartContractRegistration` entities, the key is the `code_hash` of one contract. | ||
|
|
||
| ```C# | ||
| public MappedState<Hash, SmartContractRegistration> SmartContractRegistrations { get; set; } | ||
| ``` | ||
|
|
||
| The `SmartContractRegistration` entity can be fetched by the hash value of the contract code. | ||
| It is only written once when deploying the contract. | ||
|
|
||
| The data structure that corresponds one-to-one with contracts is called `ContractInfo`. | ||
| Structure `ContractInfo` is defined in [acs0](https://docs.aelf.io/en/latest/reference/acs/acs0.html). | ||
|
|
||
| ```C# | ||
| message ContractInfo | ||
| { | ||
| // The serial number of the contract. | ||
| int64 serial_number = 1; | ||
| // The author of the contract is the person who deployed the contract. | ||
| aelf.Address author = 2; | ||
| // The category of contract code(0: C#). | ||
| sint32 category = 3; | ||
| // The hash of the contract code. | ||
| aelf.Hash code_hash = 4; | ||
| // Whether it is a system contract. | ||
| bool is_system_contract = 5; | ||
| // The version of the current contract. | ||
| int32 version = 6; | ||
| string contract_version = 7; | ||
| // Indicates if the contract is the user contract. | ||
| bool is_user_contract = 8; | ||
| } | ||
| ``` | ||
|
|
||
| We use the MappedState to store related instances. | ||
|
|
||
| ```C# | ||
| public MappedState<Address, ContractInfo> ContractInfos { get; set; } | ||
| ``` | ||
|
|
||
| From the `code_hash` field of `ContractInfo`, it is not difficult to guess: | ||
|
|
||
| 1. When trying to retrieve the contract code, the `code_hash` of ContractInfo is first read, and then the contract code itself is read from the `State.SmartContractRegistrations` mapped state. | ||
| 2. Upgrading a contract on aelf is replacing the `code_hash` of `ContractInfo`. | ||
|
|
||
| ## Deploy and update contracts | ||
|
|
||
| To deploy a smart contract to aelf, developers need to interact with the `DeploySmartContract` or `DeployUserSmartContract` defined by [acs0](https://docs.aelf.io/en/latest/reference/acs/acs0.html) and implemented by the Genesis Contract. | ||
| The differences between these two methods will be explained later. | ||
|
|
||
| When executing the deployment method, the contract code will be stored in the StateDb through the structure we mentioned before: `SmartContractRegistration`. | ||
| More specifically, it is the `code` field. | ||
|
|
||
| If developer's smart contract is written by C#, the `category` should be `0`. | ||
| The execution environment will select which runtime to load the contract code into based on the `category` field. | ||
|
|
||
| And the `code_hash` is a unique identifier for the contract code. | ||
| For C# smart contract, the code hash is calculated by the Genesis Contract during deployment. | ||
|
|
||
| After the contract code is saved in StateDb, another field is used to store the relevant information of the contract. | ||
| The structure is also mentioned before: `ContractInfo`. | ||
| There is a `code_hash` field defined in this structure, make it possible to use `GetContractInfo` method to get the contract information of provided contract address, | ||
| then use `GetSmartContractRegistrationByCodeHash` method to get contract code via contract code hash. | ||
| In addition, the contract code can also be obtained through method `GetSmartContractRegistrationByAddress`. | ||
|
|
||
| As for updating the contract code, the contract information (`ContractInfo`) can be directly modified through method `UpdateSmartContract`, | ||
| then aelf smart contract execution environment can obtain the new contract code via new contract hash from the Genesis Contract in the future. | ||
|
|
||
| ## Execution of contract code | ||
|
|
||
| Although the execution process of the contract is unrelated to the Genesis Contract. | ||
| Developers may be concerned about how their contract code will be consumed in the future after deployment. | ||
| Therefore, here are some brief explanations. | ||
|
|
||
|  | ||
|
|
||
| As shown in the above figure, assuming that the contract code has been stored in the Genesis Contract. | ||
| When a caller tries to call a method of the contract, within the aelf node, the corresponding `SmartContractRegistration` will be obtained from the Genesis Contract, the contract code will be extracted, encapsulated as an Executive type, for the contract execution environment to call. | ||
| After completing the call, return the transaction result to the caller. | ||
|
|
||
| Upgrading the contract will change the `SmartContractRegistration` obtained during the above process, so it is feasible to upgrade the deployed contract in aelf. | ||
|
|
||
| ## Calculation of contract address | ||
|
|
||
| The contract address is calculated through a field that increases with the number of contract deployments. | ||
|
|
||
| ```C# | ||
| public Int64State ContractSerialNumber { get; set; } | ||
| ``` | ||
|
|
||
| Its calculation process is located in the `DeploySmartContract` method: | ||
|
|
||
| ```C# | ||
| var contractAddress = AddressHelper.BuildContractAddress(Context.ChainId, serialNumber); | ||
| ``` | ||
|
|
||
| - The contract address of each chain of aelf is different. | ||
| - The contract address is not related to the contract code, but only to the order in which it is deployed on this chain. | ||
| - Therefore, when testing newly written contracts in `aelf-boilerplate` or `aelf-developer-tools`, the new contract always has a fixed address. | ||
|
|
||
| After the 1.6.0 version, Salt is added to the imported parameter of the deployment/upgrade contract. The contract address is calculated by using the Deployer address of the deployment account and the hash value Salt. | ||
|
|
||
| ```C# | ||
| var contractAddress = AddressHelper.ComputeContractAddress(deployer, salt); | ||
| ``` | ||
|
|
||
| - Deploying contracts with the same account and using the same Salt can make the contract address of each chain of aelf the same. | ||
|
|
||
| ## Contract deployment and update process | ||
|
|
||
| Deploy contract with audit that | ||
| you must wait for the Parliament members review and manually approve your contract | ||
| before it can enter the actual deployment process. | ||
|
|
||
| Deploy contract without audit can directly deploy your contract, | ||
| but the cost is that your contract must inherit from acs12, | ||
| which is a standard for pre-defining how contract fees should be charged when executing your contract methods. | ||
|
|
||
| ### Deploy contract with audit | ||
arg-foo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|  | ||
|
|
||
| The current pipeline starts with Propose, which generates a parliamentary proposal. | ||
| When more than 2/3 of the BPs agree to deploy/update, a new proposal is released to request code inspection. | ||
| Finally, after the code audit has passed, the real contract deployment/upgrade will be achieved through the proposal of releasing the code inspection. | ||
|
|
||
| ### Deploy contract without audit | ||
|
|
||
|  | ||
|
|
||
| Developers send deployment/update user contract transactions, generate a parliamentary CodeCheck proposal, and when more than 2/3 of the BPs conduct code checks and pass, achieve real contract deployment/upgrade through the proposal of automatically releasing code checks. | ||
|
|
||
| ### Contract deployment and upgrade new version number | ||
|
|
||
| When upgrading a contract, check the contract version information | ||
| - If the contract version is less than or equal to the original contract version, the upgrade contract transaction fails | ||
| The old version of the contract only has a version number after being upgraded. | ||
| - If the version number is increasing, the upgrade contract transaction is successful. | ||
|
|
||
| In the updateSmartContract method, increase the version number judgment: | ||
|
|
||
| ```C# | ||
| var contractInfo = Context.UpdateSmartContract(contractAddress, reg, null, info.ContractVersion); | ||
| Assert(contractInfo.IsSubsequentVersion, | ||
| $"The version to be deployed is lower than the effective version({info.ContractVersion}), please correct the version number."); | ||
| ``` | ||
|
|
||
| ## Contract error message | ||
|
|
||
| `DeployUserSmartContract` method: | ||
| - No permission. Trying to deploy a smart contract to an aelf private sidechain, and the transaction sender is not in the allowlist. | ||
| - contract code has already been deployed before. Contract code deployed. | ||
| - Already proposed. Duplicate deployment request. | ||
|
|
||
| `UpdateUserSmartContract` method: | ||
| - No permission. The transaction sender is not the contract author. | ||
| - Code is not changed. The contract code has not changed since deployment or the previous update. | ||
| - The version to be deployed is lower than the effective version({currentVersion}), please correct the version number. The updated contract version number is too low. | ||
| - Already proposed. Duplicate deployment request. | ||
|
|
||
| ## Usage | ||
| Check the `deploy` command of [aelf-command](https://docs.aelf.io/en/latest/reference/cli/methods.html#deploy-deploy-a-smart-contract). | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+78.3 KB
docs-sphinx/reference/smart-contract/images/cross-chain-class-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+11.4 KB
docs-sphinx/reference/smart-contract/images/cross-chain-token-transfer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+59.5 KB
docs-sphinx/reference/smart-contract/images/deploy-contract-with-audit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+43.6 KB
docs-sphinx/reference/smart-contract/images/deploy-contract-without-audit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+20.3 KB
docs-sphinx/reference/smart-contract/images/get-consensus-behaiviour.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+19.4 KB
docs-sphinx/reference/smart-contract/images/initialize-side-chain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+63.3 KB
docs-sphinx/reference/smart-contract/images/verify-parent-chain-tx.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| Smart Contract | ||
| ============== | ||
|
|
||
| .. toctree:: | ||
|
|
||
| Genesis Contract <genesis-contract> |
11 changes: 11 additions & 0 deletions
11
docs-sphinx/reference/smart-contract/plantuml/contract-execution.puml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| @startuml | ||
| autonumber | ||
|
|
||
| Caller -> TransactionExecutionService: Transaction | ||
| TransactionExecutionService -> SmartContractExecutiveService: Call Execute method | ||
| SmartContractExecutiveService -> GenesisContract: Call GetSmartContractRegistrationByAddress method | ||
| GenesisContract --> SmartContractExecutiveService: SmartContractRegistration instance | ||
| SmartContractExecutiveService --> TransactionExecutionService: Executive instance | ||
| TransactionExecutionService --> Caller: Transaction Result | ||
|
|
||
| @enduml |
13 changes: 13 additions & 0 deletions
13
docs-sphinx/reference/smart-contract/plantuml/cross-chain-token-transfer.puml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| @startuml | ||
|
|
||
| autonumber | ||
|
|
||
| participant "User" as U | ||
| participant "Chain A MultiToken Contract" as A | ||
| participant "Chain B MultiToken Contract" as B | ||
|
|
||
| U -> A: CrossChainTransfer | ||
| A --> U: | ||
| U -> B: CrossChainReceiveToken | ||
|
|
||
| @enduml |
23 changes: 23 additions & 0 deletions
23
docs-sphinx/reference/smart-contract/plantuml/deploy-contract-with-audit.puml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| @startuml | ||
|
|
||
| autonumber | ||
|
|
||
| Developer -> GenesisContract: ProposeNewContract / ProposeUpdateContract | ||
| GenesisContract -> ParliamentContract: CreateProposalBySystemContract | ||
| ParliamentContract -> ParliamentContract: CreateNewProposal \n(GenesisContract.ProposeContractCodeCheck) | ||
| ParliamentContract -> BlockProducer: ProposalCreated event | ||
| BlockProducer -> ParliamentContract: Approve >= 2/3 \n(ContractZero.ProposeContractCodeCheck) | ||
| ParliamentContract -> Developer: ReceiptCreated event | ||
| Developer -> GenesisContract: ReleaseApprovedContract | ||
| GenesisContract -> ParliamentContract: Release | ||
| ParliamentContract -> ParliamentContract: CreateProposalBySystemContract | ||
| ParliamentContract -> ParliamentContract: CreateNewProposal \n(ContractZero.DeploySmartContract \n/ContractZero.UpdateSmartContract) | ||
| ParliamentContract -> BlockProducer: ProposalCreated event | ||
| BlockProducer -> ParliamentContract: Approve \n(Automatically by aelf node) | ||
| ParliamentContract -> Developer: ReceiptCreated event | ||
| Developer -> GenesisContract: ReleaseCodeCheckedContract | ||
| GenesisContract -> ParliamentContract: Release | ||
| ParliamentContract -> GenesisContract: DeploySmartContract \n/UpdateSmartContract | ||
|
|
||
|
|
||
| @enduml |
16 changes: 16 additions & 0 deletions
16
docs-sphinx/reference/smart-contract/plantuml/deploy-contract-without-audit.puml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| @startuml | ||
|
|
||
| autonumber | ||
|
|
||
| Developer -> GenesisContract: DeployUserSmartContract \n/UpdateUserSmartContract | ||
| GenesisContract -> ParliamentContract: CreateProposalBySystemContract | ||
| ParliamentContract -> ParliamentContract: CreateNewProposal \n(ContractZero.PerformDeployUserSmartContract \n/ContractZero.PerformUpdateUserSmartContract) | ||
| ParliamentContract -> BlockProducer: ProposalCreated event | ||
| BlockProducer -> ParliamentContract: Approve \n(Automatically by aelf node) | ||
|
|
||
| BlockProducer -> GenesisContract: Approve>=2/3 \nReleaseApprovedUserSamrtContract \n(Automatically by aelf node) | ||
| GenesisContract -> ParliamentContract: Release | ||
| ParliamentContract -> GenesisContract: PerformDeployUserSmartContract \n/PerformUpdateUserSmartContract | ||
|
|
||
|
|
||
| @enduml |
21 changes: 21 additions & 0 deletions
21
docs-sphinx/reference/smart-contract/plantuml/get-consensus-behaiviour.puml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| @startuml | ||
| start | ||
| :GetConsensusCommand; | ||
| if (MinerList contains provided pubkey?) then (false) | ||
| :Nothing; | ||
| stop | ||
| else (true) | ||
| if (Timeslot for this BP already passed?) then (false) | ||
| if (Has this BP produced enough tiny blocks?) then (false) | ||
| :TinyBlock; | ||
| stop | ||
| else (true) | ||
| :NextRound; | ||
| stop | ||
| endif | ||
| else (true) | ||
| :NextRound; | ||
| stop | ||
| endif | ||
|
|
||
| @enduml |
16 changes: 16 additions & 0 deletions
16
docs-sphinx/reference/smart-contract/plantuml/initialize-side-chain.puml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| @startuml | ||
|
|
||
| autonumber | ||
|
|
||
| participant "SideChain CrossChain Contract" as SC | ||
| participant "SideChain" as S | ||
| participant "MainChain" as M | ||
| participant "MainChain CrossChain Contract" as MC | ||
|
|
||
| S -> S: RequestChainInitializationDataAsync | ||
| S -> M: RequestChainInitializationDataFromParentChain | ||
| M -> MC: GetChainInitializationData | ||
| MC -> S: GetInitializeMethodList | ||
| S -> SC: Initialize | ||
|
|
||
| @enduml |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.