diff --git a/contracts/blocksigner/blocksigner.go b/contracts/blocksigner/blocksigner.go index f23cfbd669..29d69d0432 100644 --- a/contracts/blocksigner/blocksigner.go +++ b/contracts/blocksigner/blocksigner.go @@ -4,6 +4,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/contracts/blocksigner/contract" + "math/big" ) type BlockSigner struct { @@ -27,7 +28,7 @@ func NewBlockSigner(transactOpts *bind.TransactOpts, contractAddr common.Address } func DeployBlockSigner(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *BlockSigner, error) { - blockSignerAddr, _, _, err := contract.DeployBlockSigner(transactOpts, contractBackend) + blockSignerAddr, _, _, err := contract.DeployBlockSigner(transactOpts, contractBackend, big.NewInt(990)) if err != nil { return blockSignerAddr, nil, err } diff --git a/contracts/blocksigner/blocksigner_test.go b/contracts/blocksigner/blocksigner_test.go index b2576203c0..d2e58b905f 100644 --- a/contracts/blocksigner/blocksigner_test.go +++ b/contracts/blocksigner/blocksigner_test.go @@ -39,7 +39,8 @@ func TestBlockSigner(t *testing.T) { } contractBackend.ForEachStorageAt(ctx, blockSignerAddress, nil, f) - signers, err := blockSigner.GetSigners(big.NewInt(0)) + byte0 := [32]byte{} + signers, err := blockSigner.GetSigners(byte0) if err != nil { t.Fatalf("can't get candidates: %v", err) } diff --git a/contracts/blocksigner/contract/BlockSigner.sol b/contracts/blocksigner/contract/BlockSigner.sol index 424427593d..3fc80b6cb1 100644 --- a/contracts/blocksigner/contract/BlockSigner.sol +++ b/contracts/blocksigner/contract/BlockSigner.sol @@ -5,20 +5,27 @@ import "./libs/SafeMath.sol"; contract BlockSigner { using SafeMath for uint256; - event Sign(address _signer, uint256 _blockNumber); + event Sign(address _signer, uint256 _blockNumber, bytes32 _blockHash); - mapping(uint256 => address[]) blockSigners; + mapping(bytes32 => address[]) blockSigners; + mapping(uint256 => bytes32[]) blocks; + uint256 public epochNumber; - function sign(uint256 _blockNumber) external { + function BlockSigner(uint256 _epochNumber) public { + epochNumber = _epochNumber; + } + + function sign(uint256 _blockNumber, bytes32 _blockHash) external { // consensus should validate all senders are validators, gas = 0 require(block.number >= _blockNumber); - require(block.number <= _blockNumber.add(990 * 2)); - blockSigners[_blockNumber].push(msg.sender); + require(block.number <= _blockNumber.add(epochNumber * 2)); + blocks[_blockNumber].push(_blockHash); + blockSigners[_blockHash].push(msg.sender); - emit Sign(msg.sender, _blockNumber); + emit Sign(msg.sender, _blockNumber, _blockHash); } - function getSigners(uint256 _blockNumber) public view returns(address[]) { - return blockSigners[_blockNumber]; + function getSigners(bytes32 _blockHash) public view returns(address[]) { + return blockSigners[_blockHash]; } } diff --git a/contracts/blocksigner/contract/blocksigner.go b/contracts/blocksigner/contract/blocksigner.go index 78fe74efd4..385c1f525c 100644 --- a/contracts/blocksigner/contract/blocksigner.go +++ b/contracts/blocksigner/contract/blocksigner.go @@ -16,18 +16,18 @@ import ( ) // BlockSignerABI is the input ABI used to generate the binding from. -const BlockSignerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"sign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"getSigners\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_signer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"Sign\",\"type\":\"event\"}]" +const BlockSignerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"sign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"getSigners\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"epochNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_epochNumber\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_signer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"Sign\",\"type\":\"event\"}]" // BlockSignerBin is the compiled bytecode used for deploying new contracts. -const BlockSignerBin = `0x6060604052341561000f57600080fd5b6102d88061001e6000396000f30060606040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632fb1b25f8114610050578063dfceceae14610068575b600080fd5b341561005b57600080fd5b6100666004356100d1565b005b341561007357600080fd5b61007e6004356101b3565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156100bd5780820151838201526020016100a5565b505050509050019250505060405180910390f35b43819010156100df57600080fd5b6100f1816107bc63ffffffff61023a16565b4311156100fd57600080fd5b600081815260208190526040902080546001810161011b8382610250565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff8116919091179091557f9a10b6124411386407c4a174729b856d293832181c352e98b5cb316b96cd3059908260405173ffffffffffffffffffffffffffffffffffffffff909216825260208201526040908101905180910390a150565b6101bb610279565b60008083815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561022e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610203575b50505050509050919050565b60008282018381101561024957fe5b9392505050565b8154818355818115116102745760008381526020902061027491810190830161028b565b505050565b60206040519081016040526000815290565b6102a991905b808211156102a55760008155600101610291565b5090565b905600a165627a7a7230582072c605c43392422edd0a185ff1131c536a80cb5329c717d23fc954f2afb51b5e0029` +const BlockSignerBin = `0x6060604052341561000f57600080fd5b604051602080610386833981016040528080516002555050610350806100366000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663e341eaa4811461005b578063e7ec6aef14610076578063f4145a83146100df575b600080fd5b341561006657600080fd5b610074600435602435610104565b005b341561008157600080fd5b61008c600435610227565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156100cb5780820151838201526020016100b3565b505050509050019250505060405180910390f35b34156100ea57600080fd5b6100f26102ac565b60405190815260200160405180910390f35b438290101561011257600080fd5b600280546101289184910263ffffffff6102b216565b43111561013457600080fd5b600082815260016020819052604090912080549091810161015583826102c8565b5060009182526020808320919091018390558282528190526040902080546001810161018183826102c8565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff8116919091179091557f62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f5490838360405173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091526040808301919091526060909101905180910390a15050565b61022f6102f1565b600082815260208181526040918290208054909290918281020190519081016040528092919081815260200182805480156102a057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610275575b50505050509050919050565b60025481565b6000828201838110156102c157fe5b9392505050565b8154818355818115116102ec576000838152602090206102ec918101908301610303565b505050565b60206040519081016040526000815290565b61032191905b8082111561031d5760008155600101610309565b5090565b905600a165627a7a72305820a8ceddaea8e4ae00991e2ae81c8c88e160dd8770f255523282c24c2df4c30ec70029` // DeployBlockSigner deploys a new Ethereum contract, binding an instance of BlockSigner to it. -func DeployBlockSigner(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *BlockSigner, error) { +func DeployBlockSigner(auth *bind.TransactOpts, backend bind.ContractBackend, _epochNumber *big.Int) (common.Address, *types.Transaction, *BlockSigner, error) { parsed, err := abi.JSON(strings.NewReader(BlockSignerABI)) if err != nil { return common.Address{}, nil, nil, err } - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(BlockSignerBin), backend) + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(BlockSignerBin), backend, _epochNumber) if err != nil { return common.Address{}, nil, nil, err } @@ -176,51 +176,77 @@ func (_BlockSigner *BlockSignerTransactorRaw) Transact(opts *bind.TransactOpts, return _BlockSigner.Contract.contract.Transact(opts, method, params...) } -// GetSigners is a free data retrieval call binding the contract method 0xdfceceae. +// EpochNumber is a free data retrieval call binding the contract method 0xf4145a83. // -// Solidity: function getSigners(_blockNumber uint256) constant returns(address[]) -func (_BlockSigner *BlockSignerCaller) GetSigners(opts *bind.CallOpts, _blockNumber *big.Int) ([]common.Address, error) { +// Solidity: function epochNumber() constant returns(uint256) +func (_BlockSigner *BlockSignerCaller) EpochNumber(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _BlockSigner.contract.Call(opts, out, "epochNumber") + return *ret0, err +} + +// EpochNumber is a free data retrieval call binding the contract method 0xf4145a83. +// +// Solidity: function epochNumber() constant returns(uint256) +func (_BlockSigner *BlockSignerSession) EpochNumber() (*big.Int, error) { + return _BlockSigner.Contract.EpochNumber(&_BlockSigner.CallOpts) +} + +// EpochNumber is a free data retrieval call binding the contract method 0xf4145a83. +// +// Solidity: function epochNumber() constant returns(uint256) +func (_BlockSigner *BlockSignerCallerSession) EpochNumber() (*big.Int, error) { + return _BlockSigner.Contract.EpochNumber(&_BlockSigner.CallOpts) +} + +// GetSigners is a free data retrieval call binding the contract method 0xe7ec6aef. +// +// Solidity: function getSigners(_blockHash bytes32) constant returns(address[]) +func (_BlockSigner *BlockSignerCaller) GetSigners(opts *bind.CallOpts, _blockHash [32]byte) ([]common.Address, error) { var ( ret0 = new([]common.Address) ) out := ret0 - err := _BlockSigner.contract.Call(opts, out, "getSigners", _blockNumber) + err := _BlockSigner.contract.Call(opts, out, "getSigners", _blockHash) return *ret0, err } -// GetSigners is a free data retrieval call binding the contract method 0xdfceceae. +// GetSigners is a free data retrieval call binding the contract method 0xe7ec6aef. // -// Solidity: function getSigners(_blockNumber uint256) constant returns(address[]) -func (_BlockSigner *BlockSignerSession) GetSigners(_blockNumber *big.Int) ([]common.Address, error) { - return _BlockSigner.Contract.GetSigners(&_BlockSigner.CallOpts, _blockNumber) +// Solidity: function getSigners(_blockHash bytes32) constant returns(address[]) +func (_BlockSigner *BlockSignerSession) GetSigners(_blockHash [32]byte) ([]common.Address, error) { + return _BlockSigner.Contract.GetSigners(&_BlockSigner.CallOpts, _blockHash) } -// GetSigners is a free data retrieval call binding the contract method 0xdfceceae. +// GetSigners is a free data retrieval call binding the contract method 0xe7ec6aef. // -// Solidity: function getSigners(_blockNumber uint256) constant returns(address[]) -func (_BlockSigner *BlockSignerCallerSession) GetSigners(_blockNumber *big.Int) ([]common.Address, error) { - return _BlockSigner.Contract.GetSigners(&_BlockSigner.CallOpts, _blockNumber) +// Solidity: function getSigners(_blockHash bytes32) constant returns(address[]) +func (_BlockSigner *BlockSignerCallerSession) GetSigners(_blockHash [32]byte) ([]common.Address, error) { + return _BlockSigner.Contract.GetSigners(&_BlockSigner.CallOpts, _blockHash) } -// Sign is a paid mutator transaction binding the contract method 0x2fb1b25f. +// Sign is a paid mutator transaction binding the contract method 0xe341eaa4. // -// Solidity: function sign(_blockNumber uint256) returns() -func (_BlockSigner *BlockSignerTransactor) Sign(opts *bind.TransactOpts, _blockNumber *big.Int) (*types.Transaction, error) { - return _BlockSigner.contract.Transact(opts, "sign", _blockNumber) +// Solidity: function sign(_blockNumber uint256, _blockHash bytes32) returns() +func (_BlockSigner *BlockSignerTransactor) Sign(opts *bind.TransactOpts, _blockNumber *big.Int, _blockHash [32]byte) (*types.Transaction, error) { + return _BlockSigner.contract.Transact(opts, "sign", _blockNumber, _blockHash) } -// Sign is a paid mutator transaction binding the contract method 0x2fb1b25f. +// Sign is a paid mutator transaction binding the contract method 0xe341eaa4. // -// Solidity: function sign(_blockNumber uint256) returns() -func (_BlockSigner *BlockSignerSession) Sign(_blockNumber *big.Int) (*types.Transaction, error) { - return _BlockSigner.Contract.Sign(&_BlockSigner.TransactOpts, _blockNumber) +// Solidity: function sign(_blockNumber uint256, _blockHash bytes32) returns() +func (_BlockSigner *BlockSignerSession) Sign(_blockNumber *big.Int, _blockHash [32]byte) (*types.Transaction, error) { + return _BlockSigner.Contract.Sign(&_BlockSigner.TransactOpts, _blockNumber, _blockHash) } -// Sign is a paid mutator transaction binding the contract method 0x2fb1b25f. +// Sign is a paid mutator transaction binding the contract method 0xe341eaa4. // -// Solidity: function sign(_blockNumber uint256) returns() -func (_BlockSigner *BlockSignerTransactorSession) Sign(_blockNumber *big.Int) (*types.Transaction, error) { - return _BlockSigner.Contract.Sign(&_BlockSigner.TransactOpts, _blockNumber) +// Solidity: function sign(_blockNumber uint256, _blockHash bytes32) returns() +func (_BlockSigner *BlockSignerTransactorSession) Sign(_blockNumber *big.Int, _blockHash [32]byte) (*types.Transaction, error) { + return _BlockSigner.Contract.Sign(&_BlockSigner.TransactOpts, _blockNumber, _blockHash) } // BlockSignerSignIterator is returned from FilterSign and is used to iterate over the raw logs and unpacked data for Sign events raised by the BlockSigner contract. @@ -294,12 +320,13 @@ func (it *BlockSignerSignIterator) Close() error { type BlockSignerSign struct { Signer common.Address BlockNumber *big.Int + BlockHash [32]byte Raw types.Log // Blockchain specific contextual infos } -// FilterSign is a free log retrieval operation binding the contract event 0x9a10b6124411386407c4a174729b856d293832181c352e98b5cb316b96cd3059. +// FilterSign is a free log retrieval operation binding the contract event 0x62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f54. // -// Solidity: event Sign(_signer address, _blockNumber uint256) +// Solidity: event Sign(_signer address, _blockNumber uint256, _blockHash bytes32) func (_BlockSigner *BlockSignerFilterer) FilterSign(opts *bind.FilterOpts) (*BlockSignerSignIterator, error) { logs, sub, err := _BlockSigner.contract.FilterLogs(opts, "Sign") @@ -309,9 +336,9 @@ func (_BlockSigner *BlockSignerFilterer) FilterSign(opts *bind.FilterOpts) (*Blo return &BlockSignerSignIterator{contract: _BlockSigner.contract, event: "Sign", logs: logs, sub: sub}, nil } -// WatchSign is a free log subscription operation binding the contract event 0x9a10b6124411386407c4a174729b856d293832181c352e98b5cb316b96cd3059. +// WatchSign is a free log subscription operation binding the contract event 0x62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f54. // -// Solidity: event Sign(_signer address, _blockNumber uint256) +// Solidity: event Sign(_signer address, _blockNumber uint256, _blockHash bytes32) func (_BlockSigner *BlockSignerFilterer) WatchSign(opts *bind.WatchOpts, sink chan<- *BlockSignerSign) (event.Subscription, error) { logs, sub, err := _BlockSigner.contract.WatchLogs(opts, "Sign")