aboutsummaryrefslogtreecommitdiffstats
path: root/contracts/checkpointoracle/oracle.go
diff options
context:
space:
mode:
Diffstat (limited to 'contracts/checkpointoracle/oracle.go')
-rw-r--r--contracts/checkpointoracle/oracle.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/contracts/checkpointoracle/oracle.go b/contracts/checkpointoracle/oracle.go
new file mode 100644
index 000000000..702e27d95
--- /dev/null
+++ b/contracts/checkpointoracle/oracle.go
@@ -0,0 +1,91 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// Package checkpointoracle is a an on-chain light client checkpoint oracle.
+package checkpointoracle
+
+//go:generate abigen --sol contract/oracle.sol --pkg contract --out contract/oracle.go
+
+import (
+ "crypto/ecdsa"
+ "errors"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/contracts/checkpointoracle/contract"
+ "github.com/ethereum/go-ethereum/core/types"
+)
+
+// CheckpointOracle is a Go wrapper around an on-chain light client checkpoint oracle.
+type CheckpointOracle struct {
+ contract *contract.CheckpointOracle
+}
+
+// NewCheckpointOracle binds checkpoint contract and returns a registrar instance.
+func NewCheckpointOracle(contractAddr common.Address, backend bind.ContractBackend) (*CheckpointOracle, error) {
+ c, err := contract.NewCheckpointOracle(contractAddr, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &CheckpointOracle{contract: c}, nil
+}
+
+// Contract returns the underlying contract instance.
+func (oracle *CheckpointOracle) Contract() *contract.CheckpointOracle {
+ return oracle.contract
+}
+
+// LookupCheckpointEvents searches checkpoint event for specific section in the
+// given log batches.
+func (oracle *CheckpointOracle) LookupCheckpointEvents(blockLogs [][]*types.Log, section uint64, hash common.Hash) []*contract.CheckpointOracleNewCheckpointVote {
+ var votes []*contract.CheckpointOracleNewCheckpointVote
+
+ for _, logs := range blockLogs {
+ for _, log := range logs {
+ event, err := oracle.contract.ParseNewCheckpointVote(*log)
+ if err != nil {
+ continue
+ }
+ if event.Index == section && common.Hash(event.CheckpointHash) == hash {
+ votes = append(votes, event)
+ }
+ }
+ }
+ return votes
+}
+
+// RegisterCheckpoint registers the checkpoint with a batch of associated signatures
+// that are collected off-chain and sorted by lexicographical order.
+//
+// Notably all signatures given should be transformed to "ethereum style" which transforms
+// v from 0/1 to 27/28 according to the yellow paper.
+func (oracle *CheckpointOracle) RegisterCheckpoint(key *ecdsa.PrivateKey, index uint64, hash []byte, rnum *big.Int, rhash [32]byte, sigs [][]byte) (*types.Transaction, error) {
+ var (
+ r [][32]byte
+ s [][32]byte
+ v []uint8
+ )
+ for i := 0; i < len(sigs); i++ {
+ if len(sigs[i]) != 65 {
+ return nil, errors.New("invalid signature")
+ }
+ r = append(r, common.BytesToHash(sigs[i][:32]))
+ s = append(s, common.BytesToHash(sigs[i][32:64]))
+ v = append(v, sigs[i][64])
+ }
+ return oracle.contract.SetCheckpoint(bind.NewKeyedTransactor(key), rnum, rhash, common.BytesToHash(hash), index, v, r, s)
+}