Conflux introduces some built-in internal contracts for better system maintenance and on-chain governance. And this document will describe how to use these built-in contracts.

idtitlecustom_edit_urlkeywords
internal_contractInternal Contracthttps://github.com/Conflux-Chain/conflux-rust/edit/master/internal_contract/README.mdconflux ,contract

( IMPORTANT: This interface will be changed in the Tethys mainnet. The documentation has been synced with the latest version. )

Conflux has introduced some embedded contracts for better system maintenance and on-chain governance. Currently Conflux contains three built-in contracts: AdminControl contract, SponsorWhitelistControl contract and Staking contract.

The solidity functional api provided by these contracts is defined here

These functions can only be called by calling the CALL or STATICCALL operations. Using operations CALLCODE or DELEGATECALL triggers the error.

The addresses of the three built-in contracts are as follows:

  • AdminControl: 0x0888000000000000000000000000000000000000
  • SponsorWhitelistControl: 0x0888000000000000000000000000000000000001
  • Staking: 0x0888000000000000000000000000000000000002

All sample code in this article will be developed using js-conflux-sdk .

AdminControl contract

Overview

AdminControl contract is a debugging tool for contract development. When a contract is created during the transaction process, the sender of the current transaction will automatically become the manager (admin) of the contract.

Managers admin address can be obtained by calling interface setAdmin(address contractAddr, address newAdmin) transferred to the management of other equity ordinary user address or zero address . And a contract cannot be a manager.

The manager of the contract has multiple administrative rights. The manager can call the destroy(address contractAddr) interface to destroy the contract, which is like calling the suicide() function through the contract. The SponsorWhitelist internal contract provides some administrator-specific functions. These functions can update the whitelist in the sponsor mechanism. We will introduce it later.

Note: For all interfaces related to administrator privileges, no errors or exceptions will be triggered during execution, regardless of whether the call is successful or not. For example, if a non-manager address attempts to transfer the manager address to itself, the transaction will succeed without any changes.

If the contract has a non-zero manager address, ConfluxScan will mark the contract in debug mode. So keep in mind that if you think your contract is ready for production, you should set the manager address to zero.

AdminControl contract also provides a query interface getAdmin(address contractAddr) that can be called by anyone.

to note:

  1. The default manager (transaction sender) is set when the contract starts to be created. So if sender A creates contract B C when the contract is built, the manager of the contract is 061e77ebaddd97 after the contract is C .
  2. However, if sender A calls contract B , and then contract B creates contract C and sets the manager to D at contract creation, the setting fails because: C contract manager is A , but created contract C The originator is B .
  3. Conflux introduces a special kind of rule. In case 2, if D is the zero address, the manager is set successfully. This means that contracts can be created explicitly stating that they do not require managers.

Sample

Consider that you can already deploy a contract with contract_addr Managers can call AdminControl.setAdmin(contract_addr, new_admin) to change the administrator as well as by calling AdminControl.destroy(contract_addr) to destroy contracts.

const PRIVATE_KEY = '0xxxxxxx';
const cfx = new Conflux({
  url: 'http://test.confluxrpc.org',
  logger: console,
});
const account = cfx.wallet.addPrivateKey(PRIVATE_KEY); // create account instance

const admin_contract = cfx.InternalContract('AdminControl')
// to change administrator
admin_contract.setAdmin(contract_addr, new_admin).sendTransaction({
  from: account,
}).confirmed();

// to kill the contract
admin_contract.destroy(contract_addr).sendTransaction({
  from: account,
}).confirmed();

SponsorWhitelistControl Contract

Overview

Conflux implements a sponsorship mechanism to subsidize users' usage of smart contracts. Therefore, as long as the transaction calling the contract is sponsored (usually sponsored by the operator of the Dapps), new accounts with zero balance will also be able to call the smart contract. Sponsorship information for smart contracts can be recorded and managed by introducing the built-in SponsorControl contract.

Conflux does not check for sponsorship again when making a message call. For example, if a regular user address A call contract B , then contract B call contract C , Conflux only checks A whether the contract B sponsorship. If A is sponsored, B will bear all gas fees and/or storage B fees during the transaction execution process, including the cost of 061e77ebaddecd calling C In other words, only the sender of the transaction can be sponsored, B cannot be sponsored.

SponsorControl contract retains the following information for each user-created contract:

  • sponsor_for_gas : is the account that provides fuel subsidies;
  • sponsor_for_collateral : is an account that provides storage mortgage subsidies;
  • sponsor_balance_for_gas : the balance available for fuel subsidies;
  • sponsor_balance_for_collateral : Balance available to provide storage mortgage subsidy;
  • sponsor_limit_for_gas_fee : is the upper bound for sponsoring gas fees per transaction;
  • whitelist : List of general user addresses eligible for subsidy, all zero addresses represent all user addresses. Only the contract itself and the administrator have permission to modify this list.

There are two resources that can be sponsored: gas costs and storage collateral.

  • *For gas cost : If a transaction calls a smart contract with a non-empty sponsor_for_gas and the transaction sender is in the contract's whitelist list, and the transaction specified gas cost is in the sponsor_limit_for_gas_fee range, the transaction's gas consumption will be from the contract's sponsor_balance_for_gas is paid in (if enough), rather than by the transaction sender's account balance, if sponsor_balance_for_gas cannot afford the gas consumption, the transaction fails. Otherwise, the transaction sender should pay gas fees.
  • For storage collateral : If a transaction calls a smart contract with a non-empty sponsor_balance_for_collateral and the transaction sender is in the contract's whitelist list, the storage collateral will be sponsor_balance_for_collateral during the execution of the transaction and will The owner of these modified storage entries is correspondingly set to the contract address. Otherwise, the transaction sender should pay for the storage collateral during execution.

When a contract is created, its sponsor_for_gas and sponsor_for_collateral will be set to zero, and the corresponding gas subsidy balance will also be zero. Both the account that provides the fuel subsidy and the account that stores the deposit subsidy can be completed by interacting with the SponsorControl contract. The current sponsor account of the contract can directly add the subsidy balance, or increase sponsor_limit_for_gas_fee under certain conditions. Other regular user accounts that provide funds higher than the current balance may replace the original sponsor. More specific details are as follows.

Sponsor Replacement

To replace sponsor_for_gas contract, the new sponsor needs to call the function setSponsorForGas(address contractAddr, uint upperBound) and transfer a fund to the built-in contract. Substitution of fuel cost sponsors can only be done if the following conditions are met:

  1. The transferred funds should be higher than the contract's current sponsor_balance_for_gas .
  2. sponsor_limit_for_gas_fee new value (is specified as upperBound parameter) should not be less than the limit of the original sponsors, unless the original sponsor_balance_for_gas can not afford to limit the original sponsors.
  3. The transferred funds should be more than 1000 times the new limit to be sufficient to subsidize transactions that call the contract 1000

If the above conditions are met, the remaining sponsor_balance_for_gas will be returned to the original sponsor sponsor_for_gas , and then the funds transferred to the built-in contract will be injected into sponsor_balance_for_gas . sponsor_for_gas and sponsor_limit_for_gas_fee will be updated with the values specified by the new patron. If the above conditions are not met, an exception will be triggered.

sponsor_for_collateral works in a similar way to replacing fuel sponsors, handling the logic without fuel allowances. The method is setSponsorForCollateral(address contractAddr) . The new sponsor needs to transfer a larger amount to the contract than the current balance. Subsequently, the current sponsor_for_collateral sponsored by 061e77ebade136 will be fully refunded, that is, the sponsor_balance_for_collateral and all the current deposit deposits of the contract, and the two fields related to deposit sponsorship will be changed accordingly according to the requirements of the new sponsor.

A contract account is also allowed to be a sponsor.

Increase the amount of sponsorship

Sponsors can provide additional sponsorship funds without having to change sponsors. In this case, the sponsor needs to call the function setSponsorForGas(address contractAddr, uint upperBound) or setSponsorForCollateral(address contractAddr) and meet the conditions 2, 3 of the three requirements for sponsor replacement. If the relevant requirements are met, the sponsorship funds of the transaction will be added to the sponsorship balance and sponsor_limit_for_gas_fee will be correspondingly renew.

Whitelist list maintenance

Only the contract itself or the contract manager can update the contract whitelist list. Sponsors have no right to change the whitelist.

Contracts can add any address to the whitelist addPrivilege(address[] memory) This means that if sponsor_for_gas is set, the contract will pay a storage deposit for accounts in the whitelist. The all-zero address is a special address 0x0000000000000000000000000000000000000000 . If the address is whitelisted, all transactions calling this contract will be sponsored. The contract can also call the method removePrivilege(address[] memory) remove some normal accounts from the whitelist. Removing a non-existing address will not cause an error or exception.

to note:

  1. A contract address can also be added to the whitelist, but this does not make any sense since only the sender of the transaction can be sponsored.

Contract managers can use addPrivilegeByAdmin(address contractAddr, address[] memory addresses) and removePrivilegeByAdmin(address contractAddr, address[] memory addresses) to maintain a whitelist.

Sample

Suppose you have a simple contract as shown below.

pragma solidity >=0.4.15;

import "https://github.com/Conflux-Chain/conflux-rust/blob/master/internal_contract/contracts/SponsorWhitelistControl.sol";

contract CommissionPrivilegeTest {
    mapping(uint => uint) public ss;

    function add(address account) public payable {
        SponsorWhitelistControl cpc = SponsorWhitelistControl(0x0888000000000000000000000000000000000001);
        address[] memory a = new address[](1);
        a[0] = account;
        cpc.addPrivilege(a);
    }

    function remove(address account) public payable {
        SponsorWhitelistControl cpc = SponsorWhitelistControl(0x0888000000000000000000000000000000000001);
        address[] memory a = new address[](1);
        a[0] = account;
        cpc.removePrivilege(a);
    }

    function foo() public payable {
    }

    function par_add(uint start, uint end) public payable {
        for (uint i = start; i < end; i++) {
            ss[i] = 1;
        }
    }
}

The contract is deployed and the address is contract_addr If someone wishes to sponsor the gas fee, he/she can send a transaction like this:

const PRIVATE_KEY = '0xxxxxxx';
const cfx = new Conflux({
  url: 'http://test.confluxrpc.org',
  logger: console,
});
const account = cfx.wallet.addPrivateKey(PRIVATE_KEY); // create account instance

const sponsor_contract = cfx.InternalContract('SponsorWhitelistControl');
sponsor_contract.setSponsorForGas(contract_addr, your_upper_bound).sendTransaction({
  from: account,
  value: your_sponsor_value
}).confirmed();

If you need sponsorship to store collateral, can simply setSponsorForGas(contract_addr, your_upper_bound) replaced setSponsorForCollateral(contract_addr) can.

After that you can use addPrivilege and removePrivilege whitelist for your contract. The special all-zero address 0x0000000000000000000000000000000000000000 means everyone is in whitelist . Use with caution.

you_contract.add(white_list_addr).sendTransaction({
  from: account,
})

you_contract.remove(white_list_addr).sendTransaction({
  from: account,
})

Then whitelist account in the call you_contract.foo() or you_contract.par_add(1, 10) time, will not pay any fees.

Staking contract

Overview

There are two reasons for Conflux to introduce the equity pledge mechanism: First, the equity mechanism provides a better charging method for occupying storage space (compared to "pay once, occupy forever"). Second, the mechanism also helps define voting rights in decentralized governance.

At the top level, Conflux implements a built-in Staking contract to record stake information for all accounts. By sending transactions to this contract, users (including external users and smart contracts) can deposit/withdraw funds, also known as staking within the contract. The interest on the pledged funds is paid at the time of withdrawal, and the amount depends on the amount withdrawn and the duration of the pledge.

The user can deposit the amount for deposit(uint amount) by calling 061e77ebade358, and then the funds amount will be moved balance stakingBalance . It should be noted that this function is not payable , the user only needs to specify the amount of the mortgage without transferring funds into into the internal contract.

Users can also withdraw their balance withdraw(uint amount) The caller can call this function to withdraw some tokens from the Conflux embedded staking contract. This triggers interest settlement. Mortgage funds and interest will be transferred to the user's balance in a timely manner. The order of all withdrawals will be processed on a first come, first served basis.

interest rate

The current annualized interest rate is 4.08%. Compound interest is achieved at the granularity of blocks.

If the execution block B when transactions, trying to extract value v and block B' funding mortgages, the interest is calculated as follows:

interest issued = v * (1 + 4% / 63072000)^T - v

Among them, T = BlockNo(B)−BlockNo(B') is the pledge duration measured by the number of blocks, and 63072000 is the expected value of the number of blocks generated in 365 days under the premise that the block generation time is 0.5

Lock and Voting

By locking the pledge balance, users can obtain voting rights for further on-chain governance. By calling voteLock(uint amount, uint unlock_block_number) function, an account can make the following commitments: "My stakingBalance in the future unlock_block_number always have at least will amount of funds." A single account can make multiple commitments, such as "I will hold at least 10CFX this year and at least 5CFX next year." Once a commitment is made, it cannot be cancelled! But the account can overwrite the original commitment by locking in a larger amount. Whenever an account attempts to withdraw stakingBalance , the internal contract checks whether the remaining balance matches the lock commitment.

Here we will introduce the logical details of locking balances with a few examples. Conflux assume the remainder of the year will produce x blocks, produced next year in y blocks. Since the Conflux network can generate two blocks per second, y approximately equal to 2 * 60 * 60 * 24 * 365 . And x depends on when you read the article.

  1. Suppose an account has stakingBalance in 061e77ebade48a, if it calls voteLock(100 * 10^18, x) , it means that the account tries to lock 100CFX. But because it lacks enough stakingBalance , the transaction execution fails.
  2. However, if the account calls voteLock(8 * 10^18, x) , the transaction will succeed.
  3. Subsequently, if the account calls voteLock(6 * 10^18, x+y) , the transaction will also succeed. This means that 2CFX will be unlocked at the end of this year after the trade is executed, while another 6CFX will be locked until the end of next year.
  4. If the account calls voteLock(0, x) , nothing will happen. Transactions do not trigger errors during transaction execution. The built-in contract treats this call as a meaningless promise: the account re-commits to lock at least 0 CFX by the end of the year, provided the old promises made in steps 2 and 3 are valid.
  5. If the account calls voteLock(9 * 10^18, x+y) , the two older commitments will be overwritten as "Lock 9CFX until the end of next year is a stronger commitment".

Lockup has no effect on interest. When the account successfully withdraws the mortgage balance, the interest will be calculated as usual.

At any time, each locked amount will be assigned voting rights 0 to 1 according to its unlock time. Parts with a lock-up period of more than 1 year will have full voting rights. See section 8.3.2 of the Conflux Protocol Specification

Sample

const PRIVATE_KEY = '0xxxxxxx';
const cfx = new Conflux({
  url: 'http://test.confluxrpc.org',
  logger: console,
});
const account = cfx.wallet.addPrivateKey(PRIVATE_KEY); // create account instance

const staking_contract = cfx.InternalContract('Staking');
// deposit some amount of tokens
staking_contract.deposit(your_number_of_tokens).sendTransaction({
  from: account,
}).confirmed();

// withdraw some amount of tokens
staking_contract.withdraw(your_number_of_tokens).sendTransaction({
  from: account,
}).confirmed();

// lock some tokens until some block number
staking_contract.voteLock(your_number_of_tokens, your_unlock_block_number).sendTransaction({
  from: account,
}).confirmed();

Related database:


Conflux中文社区
66 声望19 粉丝

Conflux网址:[链接]