Bridge Contract for smart contract source code analysis

 

source code

For the description of the algorithm, see my blog post - Effectively Cross-chain Between Ethereum EVM-based Chains . The following mainly analyzes the smart contract code: 

Bridge.sol

data structure

Validator Rewards:

reward = base + a*n (n is the number of blocks proposed in Header = end-start)

struct Reward {
    uint256 base;
    uint256 a;
}

Reward reward;
uint256 public maxReward;

Epoch random number seed

bytes32 public epochSeed = keccak256(block.difficulty + block.number + now);

 Chip/Margin (Stake)

struct Stake {           // Validator预付的保证金金额及validator的地址
    uint256 amount;
    address staker;
}
mapping(address => uint256) stakers;   // Validator Map
Stake[] stakes;                        // 保证金数组
uint256 public stakeSum;               // 保证金总额
address public stakeToken;             // 保证金的币种

global variable


// 连续块头的默克尔树的根
mapping(address => bytes32[]) roots;

// 每一个桥接链的最后一块的块号
mapping(address => uint256) lastBlock;

// 只有Admin才能创建和建立侧链和主链的映射
// fromChainId => (oldTokenAddr => newTokenAddr)
mapping(address => mapping(address => address)) tokens;Block


// 对一个给定的链,一个特定的EPOCH,记录开始块和终块并提供Headerroot
event RootStorage(address indexed chain, uint256 indexed start,
    uint256 indexed end, bytes32 headerRoot, uint256 i, address proposer);
event Deposit(address indexed user, address indexed toChain,
    address indexed depositToken, address fromChain, uint256 amount);
event Withdraw(address indexed user, address indexed fromChain,
    address indexed withdrawToken, uint256 amount);
event TokenAdded(address indexed fromChain, address indexed origToken,
    address indexed newToken);
event TokenAssociated(address indexed toChain, address indexed fromToken,
    address indexed toToken);

Withdraw

  // Pending withdrawals. The user prepares a withdrawal with tx data and then
  // releases it with a withdraw. It can be overwritten by the user and gets wiped
  // upon withdrawal.
  struct Withdrawal {
    address withdrawToken;          // Token to withdraw (i.e. the one mapped to deposit)
    address fromChain;
    uint256 amount;         // Number of atomic units to withdraw
    bytes32 txRoot;         // Transactions root for the block housing this tx
    bytes32 txHash;         // Hash of this tx
    bytes32 receiptsRoot;   // Receipts root for the block housing this tx
  }
  mapping(address => Withdrawal) pendingWithdrawals;

 

main function

Margin/Stake

stake(uint256 amount)

Top up margin in a specific currency. Set the recharge currency, recharge amount/total amount, and store it in the Validator array

destake(uint256 amount)

Revocation of security deposit. Adjust recharge amount/total amount

function proposeRoot(bytes32 headerRoot, address chainId, uint256 end, bytes sigs)

Store Headerroot in the roots array

Calculate reward amount and send

生成EpochSeed=keccak256(block.difficulty + block.number + now);

Send RootStorage Event

Record this Epoch's Last Block

Helper function

function toBytes(address a) constant returns (bytes b) 

function toBytes(uint256 x) returns (bytes b) 

function encodeAddress(address a) returns(bytes) 


function getStake(address a) public constant returns (uint256) 

function getStakeIndex(address a) public constant returns (uint256) 

function getLastBlock(address fromChain) public constant returns (uint256) 

// 挑选提议者。被挑中的概率取决于保证金额大小
function getProposer() public constant returns (address) 

function getTokenMapping(address chain, address token) public constant returns (address) 

// 取32 bytes强制类型转换成byes32
function getBytes32(uint64 start, bytes data) pure returns (bytes32) 
// 取32 bytes强制类型转换成uint256
function getUint256(uint64 start, bytes data) pure returns (uint256)

// 取8 bytes强制类型转换成uint64
function getUint64(uint64 start, bytes data) pure returns (uint64) 

// 'proof' is a concatenated set of [right][hash], i.e. 33 byte chunks
function merkleProof(bytes32 leaf, bytes32 targetHash, bytes proof) private constant returns (bool) 


// Change the number of validators required to allow a passed header root
function updateValidatorThreshold(uint256 newThreshold) public onlyAdmin()

// The admin can update the reward at any time.
function updateReward(uint256 base, uint256 a, uint256 max) public onlyAdmin() 

// 保证金币种只能在实例初始化的时候设定
function Bridge(address token) 

modifier onlyAdmin() 

 

deploy

refer to this source code

client --add http://localhost:7545,0x27fa13e74d1aff21d18119053fbbe1b7e10ba0d0,http://localhost:8545,0xb85cae815b3f05b0c8c8f277312dba1f747d3171
  1. Deploy two identical Bridge contracts to two EVM-based chains. (one is called the main chain and one is the side chain)
  2. Participants enter the Proposer standby pool by calling Bridge.stake() to pre-pay the deposit (stake).
  3. Whenever the data is sent to the Bridge contract, a new Proposer is selected based on the size of the margin
  4. This Proposer listens to messages from the sidechain and collects block headers.

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325055129&siteId=291194637
Recommended