Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions docs-sphinx/reference/smart-contract/genesis-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,115 @@ message SmartContractRegistration {
bool is_user_contract = 8;
}
```
Smart Contract code is store in the `code` field.

However, each `SmartContractRegistration` entity is not a one-to-one correspondence with the contract, and its storage structure is:

```C#
public MappedState<Hash, SmartContractRegistration> SmartContractRegistrations { get; set; }
```

`SmartContractRegistration` entity can be fetched by the hash value of the contract code. In fact, 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.proto`.

```C#
message ContractInfo
{
// The serial number of the contract.
int64 serial_number = 1;
// The author of the contract, this 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 `State.SmartContractRegistrations` mapped state.
2. Upgrading a contract on aelf is actually replacing the `code_hash` of `ContractInfo`.

# Calculation of contract address

The contract address is actually 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

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 inspection is passed, the real contract deployment/upgrade will be achieved through the proposal of releasing 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


| Method | Error message | Note |
| --- | --- | --- |
| DeployUserSmartContract | No permission. | Trying to deploy smart contract to an aelf private sidechain, and the transaction sender is not in allowlist. |
| | contract code has already been deployed before. | Contract code deployed |
| | Already proposed. | Duplicate deployment request |
| UpdateUserSmartContract | Contract not found. | Contract does not exist |
| | No permission. | The updated contract author is not myself |
| | Code is not changed. | The contract code has not changed |
| | contract code has already been deployed before. | Contract code deployed |
| | The version to be deployed is lower than the effective version({currentVersion}), please correct the version number. | Updated contract version number is too low |
| | Already proposed. | Duplicate update request |