bsc
创世合约里配置了系统合约,且地址是写死的,比如0x00000000000000001001, 会分配初始钱
然后会在第一个块进行初始化的调用。
使用案例
a: 获取validator ,这个方式是通过eth api 调用,因为不需要网络通信延迟,所以很快
method := "getValidators"
// 指定的方法名和参数列表打包成一个 ABI 编码的字节数组
data, err := p.validatorSetABIBeforeLuban.Pack(method)
// 系统合约调用
msgData := (hexutil.Bytes)(data)
toAddress := common.HexToAddress(systemcontracts.ValidatorContract)
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
result, err := p.ethAPI.Call(ctx, ethapi.TransactionArgs{
Gas: &gas,
To: &toAddress,
Data: &msgData,
}, blockNr, nil)
// 将一个 ABI 编码的返回结果反序列化为含有具体类型数据的 Go 结构体(valSet)
var valSet []common.Address
err = p.validatorSetABIBeforeLuban.UnpackIntoInterface(&valSet, method, result)b: 分配奖励
惩罚和分配奖励是由出块人来做的事情,也就是from是miner,to 是要调用的合约,在finalize阶段会创建,并且在其阶段就会处理完这个交易,直接通过callmsg来生成消息,然后通过applyTransaction底层操作。
// 生成系统交易
method := "distributeFinalityReward"
data, err := p.validatorSetABI.Pack(method, validators, weights)
if err != nil {
log.Error("Unable to pack tx for distributeFinalityReward", "error", err)
return err
}
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, common.Big0)
return p.applyTransaction(msg, state, header, cx, txs, receipts, systemTxs, usedGas, mining)
quorum
预编译合约
以太坊的预编译合约不需要部署到以太坊上,因为它们已经作为区块链客户端(如 geth 或 OpenEthereum)的一部分实现。预编译合约主要用于处理复杂的计算,如加密哈希函数、椭圆曲线签名验证等,它们的地址是预先定义的,通常是较低的地址。
这些预编译合约的主要目的是提高某些计算密集型操作的性能。它们是在客户端的底层代码中实现的,而不是智能合约字节码。当 EVM 遇到一个预编译合约的地址时,它将直接调用相应的底层代码实现,而不是执行合约字节码。这样可以显著提高这些操作的执行速度。
原理:
生成的EVM指令中,Solidity编译器会将预编译合约ecrecover的地址(0x1)作为目标地址。接着,在EVM执行STATICCALL指令时,它会检查这个目标地址并发现它对应一个预编译合约,然后调用相应的底层实现