mirror of https://github.com/ethereum/go-ethereum
parent
d89ea3e6f9
commit
178da7c6a9
@ -0,0 +1,181 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the accounts package to support client side key
|
||||||
|
// management on mobile platforms.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
// StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB
|
||||||
|
// memory and taking approximately 1s CPU time on a modern processor.
|
||||||
|
StandardScryptN = int(accounts.StandardScryptN) |
||||||
|
|
||||||
|
// StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB
|
||||||
|
// memory and taking approximately 1s CPU time on a modern processor.
|
||||||
|
StandardScryptP = int(accounts.StandardScryptP) |
||||||
|
|
||||||
|
// LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB
|
||||||
|
// memory and taking approximately 100ms CPU time on a modern processor.
|
||||||
|
LightScryptN = int(accounts.LightScryptN) |
||||||
|
|
||||||
|
// LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB
|
||||||
|
// memory and taking approximately 100ms CPU time on a modern processor.
|
||||||
|
LightScryptP = int(accounts.LightScryptP) |
||||||
|
) |
||||||
|
|
||||||
|
// Account represents a stored key.
|
||||||
|
type Account struct{ account accounts.Account } |
||||||
|
|
||||||
|
// Accounts represents a slice of accounts.
|
||||||
|
type Accounts struct{ accounts []accounts.Account } |
||||||
|
|
||||||
|
// Size returns the number of accounts in the slice.
|
||||||
|
func (a *Accounts) Size() int { |
||||||
|
return len(a.accounts) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the account at the given index from the slice.
|
||||||
|
func (a *Accounts) Get(index int) (*Account, error) { |
||||||
|
if index < 0 || index >= len(a.accounts) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Account{a.accounts[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Set sets the account at the given index in the slice.
|
||||||
|
func (a *Accounts) Set(index int, account *Account) error { |
||||||
|
if index < 0 || index >= len(a.accounts) { |
||||||
|
return errors.New("index out of bounds") |
||||||
|
} |
||||||
|
a.accounts[index] = account.account |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// GetAddress retrieves the address associated with the account.
|
||||||
|
func (a *Account) GetAddress() *Address { |
||||||
|
return &Address{a.account.Address} |
||||||
|
} |
||||||
|
|
||||||
|
// GetFile retrieves the path of the file containing the account key.
|
||||||
|
func (a *Account) GetFile() string { |
||||||
|
return a.account.File |
||||||
|
} |
||||||
|
|
||||||
|
// AccountManager manages a key storage directory on disk.
|
||||||
|
type AccountManager struct{ manager *accounts.Manager } |
||||||
|
|
||||||
|
// NewAccountManager creates a manager for the given directory.
|
||||||
|
func NewAccountManager(keydir string, scryptN, scryptP int) *AccountManager { |
||||||
|
return &AccountManager{manager: accounts.NewManager(keydir, scryptN, scryptP)} |
||||||
|
} |
||||||
|
|
||||||
|
// HasAddress reports whether a key with the given address is present.
|
||||||
|
func (am *AccountManager) HasAddress(addr *Address) bool { |
||||||
|
return am.manager.HasAddress(addr.address) |
||||||
|
} |
||||||
|
|
||||||
|
// GetAccounts returns all key files present in the directory.
|
||||||
|
func (am *AccountManager) GetAccounts() *Accounts { |
||||||
|
return &Accounts{am.manager.Accounts()} |
||||||
|
} |
||||||
|
|
||||||
|
// DeleteAccount deletes the key matched by account if the passphrase is correct.
|
||||||
|
// If a contains no filename, the address must match a unique key.
|
||||||
|
func (am *AccountManager) DeleteAccount(a *Account, passphrase string) error { |
||||||
|
return am.manager.DeleteAccount(accounts.Account{ |
||||||
|
Address: a.account.Address, |
||||||
|
File: a.account.File, |
||||||
|
}, passphrase) |
||||||
|
} |
||||||
|
|
||||||
|
// Sign signs hash with an unlocked private key matching the given address.
|
||||||
|
func (am *AccountManager) Sign(addr *Address, hash []byte) ([]byte, error) { |
||||||
|
return am.manager.Sign(addr.address, hash) |
||||||
|
} |
||||||
|
|
||||||
|
// SignWithPassphrase signs hash if the private key matching the given address can be
|
||||||
|
// decrypted with the given passphrase.
|
||||||
|
func (am *AccountManager) SignWithPassphrase(addr *Address, passphrase string, hash []byte) ([]byte, error) { |
||||||
|
return am.manager.SignWithPassphrase(addr.address, passphrase, hash) |
||||||
|
} |
||||||
|
|
||||||
|
// Unlock unlocks the given account indefinitely.
|
||||||
|
func (am *AccountManager) Unlock(a *Account, passphrase string) error { |
||||||
|
return am.manager.TimedUnlock(a.account, passphrase, 0) |
||||||
|
} |
||||||
|
|
||||||
|
// Lock removes the private key with the given address from memory.
|
||||||
|
func (am *AccountManager) Lock(addr *Address) error { |
||||||
|
return am.manager.Lock(addr.address) |
||||||
|
} |
||||||
|
|
||||||
|
// TimedUnlock unlocks the given account with the passphrase. The account
|
||||||
|
// stays unlocked for the duration of timeout. A timeout of 0 unlocks the account
|
||||||
|
// until the program exits. The account must match a unique key file.
|
||||||
|
//
|
||||||
|
// If the account address is already unlocked for a duration, TimedUnlock extends or
|
||||||
|
// shortens the active unlock timeout. If the address was previously unlocked
|
||||||
|
// indefinitely the timeout is not altered.
|
||||||
|
func (am *AccountManager) TimedUnlock(a *Account, passphrase string, timeout int64) error { |
||||||
|
return am.manager.TimedUnlock(a.account, passphrase, time.Duration(timeout)) |
||||||
|
} |
||||||
|
|
||||||
|
// NewAccount generates a new key and stores it into the key directory,
|
||||||
|
// encrypting it with the passphrase.
|
||||||
|
func (am *AccountManager) NewAccount(passphrase string) (*Account, error) { |
||||||
|
account, err := am.manager.NewAccount(passphrase) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &Account{account}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// ExportKey exports as a JSON key, encrypted with newPassphrase.
|
||||||
|
func (am *AccountManager) ExportKey(a *Account, passphrase, newPassphrase string) ([]byte, error) { |
||||||
|
return am.manager.Export(a.account, passphrase, newPassphrase) |
||||||
|
} |
||||||
|
|
||||||
|
// ImportKey stores the given encrypted JSON key into the key directory.
|
||||||
|
func (am *AccountManager) ImportKey(keyJSON []byte, passphrase, newPassphrase string) (*Account, error) { |
||||||
|
account, err := am.manager.Import(keyJSON, passphrase, newPassphrase) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &Account{account}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Update changes the passphrase of an existing account.
|
||||||
|
func (am *AccountManager) Update(a *Account, passphrase, newPassphrase string) error { |
||||||
|
return am.manager.Update(a.account, passphrase, newPassphrase) |
||||||
|
} |
||||||
|
|
||||||
|
// ImportPreSaleKey decrypts the given Ethereum presale wallet and stores
|
||||||
|
// a key file in the key directory. The key file is encrypted with the same passphrase.
|
||||||
|
func (am *AccountManager) ImportPreSaleKey(keyJSON []byte, passphrase string) (*Account, error) { |
||||||
|
account, err := am.manager.ImportPreSaleKey(keyJSON, passphrase) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &Account{account}, nil |
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the math/big package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"math/big" |
||||||
|
) |
||||||
|
|
||||||
|
// A BigInt represents a signed multi-precision integer.
|
||||||
|
type BigInt struct { |
||||||
|
bigint *big.Int |
||||||
|
} |
||||||
|
|
||||||
|
// NewBigInt allocates and returns a new BigInt set to x.
|
||||||
|
func NewBigInt(x int64) *BigInt { |
||||||
|
return &BigInt{big.NewInt(x)} |
||||||
|
} |
||||||
|
|
||||||
|
// GetBytes returns the absolute value of x as a big-endian byte slice.
|
||||||
|
func (bi *BigInt) GetBytes() []byte { |
||||||
|
return bi.bigint.Bytes() |
||||||
|
} |
||||||
|
|
||||||
|
// String returns the value of x as a formatted decimal string.
|
||||||
|
func (bi *BigInt) String() string { |
||||||
|
return bi.bigint.String() |
||||||
|
} |
||||||
|
|
||||||
|
// GetInt64 returns the int64 representation of x. If x cannot be represented in
|
||||||
|
// an int64, the result is undefined.
|
||||||
|
func (bi *BigInt) GetInt64() int64 { |
||||||
|
return bi.bigint.Int64() |
||||||
|
} |
||||||
|
|
||||||
|
// SetBytes interprets buf as the bytes of a big-endian unsigned integer and sets
|
||||||
|
// the big int to that value.
|
||||||
|
func (bi *BigInt) SetBytes(buf []byte) { |
||||||
|
bi.bigint.SetBytes(buf) |
||||||
|
} |
||||||
|
|
||||||
|
// SetInt64 sets the big int to x.
|
||||||
|
func (bi *BigInt) SetInt64(x int64) { |
||||||
|
bi.bigint.SetInt64(x) |
||||||
|
} |
||||||
|
|
||||||
|
// SetString sets the big int to x.
|
||||||
|
//
|
||||||
|
// The string prefix determines the actual conversion base. A prefix of "0x" or
|
||||||
|
// "0X" selects base 16; the "0" prefix selects base 8, and a "0b" or "0B" prefix
|
||||||
|
// selects base 2. Otherwise the selected base is 10.
|
||||||
|
func (bi *BigInt) SetString(x string, base int) { |
||||||
|
bi.bigint.SetString(x, base) |
||||||
|
} |
||||||
|
|
||||||
|
// BigInts represents a slice of big ints.
|
||||||
|
type BigInts struct{ bigints []*big.Int } |
||||||
|
|
||||||
|
// Size returns the number of big ints in the slice.
|
||||||
|
func (bi *BigInts) Size() int { |
||||||
|
return len(bi.bigints) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the bigint at the given index from the slice.
|
||||||
|
func (bi *BigInts) Get(index int) (*BigInt, error) { |
||||||
|
if index < 0 || index >= len(bi.bigints) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &BigInt{bi.bigints[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Set sets the big int at the given index in the slice.
|
||||||
|
func (bi *BigInts) Set(index int, bigint *BigInt) error { |
||||||
|
if index < 0 || index >= len(bi.bigints) { |
||||||
|
return errors.New("index out of bounds") |
||||||
|
} |
||||||
|
bi.bigints[index] = bigint.bigint |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains the wrappers from the math/big package that require Go 1.7 and above.
|
||||||
|
|
||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
// GetString returns the value of x as a formatted string in some number base.
|
||||||
|
func (bi *BigInt) GetString(base int) string { |
||||||
|
return bi.bigint.Text(base) |
||||||
|
} |
@ -0,0 +1,202 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the bind package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"math/big" |
||||||
|
"strings" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi" |
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi/bind" |
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/core/types" |
||||||
|
) |
||||||
|
|
||||||
|
// Signer is an interaface defining the callback when a contract requires a
|
||||||
|
// method to sign the transaction before submission.
|
||||||
|
type Signer interface { |
||||||
|
Sign(*Address, *Transaction) (*Transaction, error) |
||||||
|
} |
||||||
|
|
||||||
|
type signer struct { |
||||||
|
sign bind.SignerFn |
||||||
|
} |
||||||
|
|
||||||
|
func (s *signer) Sign(addr *Address, tx *Transaction) (*Transaction, error) { |
||||||
|
sig, err := s.sign(addr.address, tx.tx) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &Transaction{sig}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// CallOpts is the collection of options to fine tune a contract call request.
|
||||||
|
type CallOpts struct { |
||||||
|
opts bind.CallOpts |
||||||
|
} |
||||||
|
|
||||||
|
// NewCallOpts creates a new option set for contract calls.
|
||||||
|
func NewCallOpts() *CallOpts { |
||||||
|
return new(CallOpts) |
||||||
|
} |
||||||
|
|
||||||
|
func (opts *CallOpts) IsPending() bool { return opts.opts.Pending } |
||||||
|
func (opts *CallOpts) GetGasLimit() int64 { return 0 /* TODO(karalabe) */ } |
||||||
|
|
||||||
|
// GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876)
|
||||||
|
// Even then it's awkward to unpack the subtleties of a Go context out to Java.
|
||||||
|
// func (opts *CallOpts) GetContext() *Context { return &Context{opts.opts.Context} }
|
||||||
|
|
||||||
|
func (opts *CallOpts) SetPending(pending bool) { opts.opts.Pending = pending } |
||||||
|
func (opts *CallOpts) SetGasLimit(limit int64) { /* TODO(karalabe) */ } |
||||||
|
func (opts *CallOpts) SetContext(context *Context) { opts.opts.Context = context.context } |
||||||
|
|
||||||
|
// TransactOpts is the collection of authorization data required to create a
|
||||||
|
// valid Ethereum transaction.
|
||||||
|
type TransactOpts struct { |
||||||
|
opts bind.TransactOpts |
||||||
|
} |
||||||
|
|
||||||
|
func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From} } |
||||||
|
func (opts *TransactOpts) GetNonce() int64 { return opts.opts.Nonce.Int64() } |
||||||
|
func (opts *TransactOpts) GetValue() *BigInt { return &BigInt{opts.opts.Value} } |
||||||
|
func (opts *TransactOpts) GetGasPrice() *BigInt { return &BigInt{opts.opts.GasPrice} } |
||||||
|
func (opts *TransactOpts) GetGasLimit() int64 { return opts.opts.GasLimit.Int64() } |
||||||
|
|
||||||
|
// GetSigner cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876)
|
||||||
|
// func (opts *TransactOpts) GetSigner() Signer { return &signer{opts.opts.Signer} }
|
||||||
|
|
||||||
|
// GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876)
|
||||||
|
// Even then it's awkward to unpack the subtleties of a Go context out to Java.
|
||||||
|
//func (opts *TransactOpts) GetContext() *Context { return &Context{opts.opts.Context} }
|
||||||
|
|
||||||
|
func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address } |
||||||
|
func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) } |
||||||
|
func (opts *TransactOpts) SetSigner(s Signer) { |
||||||
|
opts.opts.Signer = func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { |
||||||
|
sig, err := s.Sign(&Address{addr}, &Transaction{tx}) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return sig.tx, nil |
||||||
|
} |
||||||
|
} |
||||||
|
func (opts *TransactOpts) SetValue(value *BigInt) { opts.opts.Value = value.bigint } |
||||||
|
func (opts *TransactOpts) SetGasPrice(price *BigInt) { opts.opts.GasPrice = price.bigint } |
||||||
|
func (opts *TransactOpts) SetGasLimit(limit int64) { opts.opts.GasLimit = big.NewInt(limit) } |
||||||
|
func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context } |
||||||
|
|
||||||
|
// BoundContract is the base wrapper object that reflects a contract on the
|
||||||
|
// Ethereum network. It contains a collection of methods that are used by the
|
||||||
|
// higher level contract bindings to operate.
|
||||||
|
type BoundContract struct { |
||||||
|
contract *bind.BoundContract |
||||||
|
address common.Address |
||||||
|
deployer *types.Transaction |
||||||
|
} |
||||||
|
|
||||||
|
// DeployContract deploys a contract onto the Ethereum blockchain and binds the
|
||||||
|
// deployment address with a wrapper.
|
||||||
|
func DeployContract(opts *TransactOpts, abiJSON string, bytecode []byte, client *EthereumClient, args *Interfaces) (*BoundContract, error) { |
||||||
|
// Convert all the deployment parameters to Go types
|
||||||
|
params := make([]interface{}, len(args.objects)) |
||||||
|
for i, obj := range args.objects { |
||||||
|
params[i] = obj |
||||||
|
} |
||||||
|
// Deploy the contract to the network
|
||||||
|
parsed, err := abi.JSON(strings.NewReader(abiJSON)) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
addr, tx, bound, err := bind.DeployContract(&opts.opts, parsed, bytecode, client.client, params...) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &BoundContract{ |
||||||
|
contract: bound, |
||||||
|
address: addr, |
||||||
|
deployer: tx, |
||||||
|
}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// BindContract creates a low level contract interface through which calls and
|
||||||
|
// transactions may be made through.
|
||||||
|
func BindContract(address *Address, abiJSON string, client *EthereumClient) (*BoundContract, error) { |
||||||
|
parsed, err := abi.JSON(strings.NewReader(abiJSON)) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &BoundContract{ |
||||||
|
contract: bind.NewBoundContract(address.address, parsed, client.client, client.client), |
||||||
|
address: address.address, |
||||||
|
}, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (c *BoundContract) GetAddress() *Address { return &Address{c.address} } |
||||||
|
func (c *BoundContract) GetDeployer() *Transaction { |
||||||
|
if c.deployer == nil { |
||||||
|
return nil |
||||||
|
} |
||||||
|
return &Transaction{c.deployer} |
||||||
|
} |
||||||
|
|
||||||
|
// Call invokes the (constant) contract method with params as input values and
|
||||||
|
// sets the output to result.
|
||||||
|
func (c *BoundContract) Call(opts *CallOpts, out *Interfaces, method string, args *Interfaces) error { |
||||||
|
// Convert all the input and output parameters to Go types
|
||||||
|
params := make([]interface{}, len(args.objects)) |
||||||
|
for i, obj := range args.objects { |
||||||
|
params[i] = obj |
||||||
|
} |
||||||
|
results := make([]interface{}, len(out.objects)) |
||||||
|
for i, obj := range out.objects { |
||||||
|
results[i] = obj |
||||||
|
} |
||||||
|
// Execute the call to the contract and wrap any results
|
||||||
|
if err := c.contract.Call(&opts.opts, &results, method, params...); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
for i, res := range results { |
||||||
|
out.objects[i] = res |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// Transact invokes the (paid) contract method with params as input values.
|
||||||
|
func (c *BoundContract) Transact(opts *TransactOpts, method string, args *Interfaces) (*Transaction, error) { |
||||||
|
params := make([]interface{}, len(args.objects)) |
||||||
|
for i, obj := range args.objects { |
||||||
|
params[i] = obj |
||||||
|
} |
||||||
|
tx, err := c.contract.Transact(&opts.opts, method, params) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &Transaction{tx}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Transfer initiates a plain transaction to move funds to the contract, calling
|
||||||
|
// its default method if one is available.
|
||||||
|
func (c *BoundContract) Transfer(opts *TransactOpts) (*Transaction, error) { |
||||||
|
tx, err := c.contract.Transfer(&opts.opts) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &Transaction{tx}, nil |
||||||
|
} |
@ -0,0 +1,187 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the common package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/hex" |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
) |
||||||
|
|
||||||
|
// Hash represents the 32 byte Keccak256 hash of arbitrary data.
|
||||||
|
type Hash struct { |
||||||
|
hash common.Hash |
||||||
|
} |
||||||
|
|
||||||
|
// NewHashFromBytes converts a slice of bytes to a hash value.
|
||||||
|
func NewHashFromBytes(hash []byte) (*Hash, error) { |
||||||
|
h := new(Hash) |
||||||
|
if err := h.SetBytes(hash); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return h, nil |
||||||
|
} |
||||||
|
|
||||||
|
// NewHashFromHex converts a hex string to a hash value.
|
||||||
|
func NewHashFromHex(hash string) (*Hash, error) { |
||||||
|
h := new(Hash) |
||||||
|
if err := h.SetHex(hash); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return h, nil |
||||||
|
} |
||||||
|
|
||||||
|
// SetBytes sets the specified slice of bytes as the hash value.
|
||||||
|
func (h *Hash) SetBytes(hash []byte) error { |
||||||
|
if length := len(hash); length != common.HashLength { |
||||||
|
return fmt.Errorf("invalid hash length: %v != %v", length, common.HashLength) |
||||||
|
} |
||||||
|
copy(h.hash[:], hash) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// GetBytes retrieves the byte representation of the hash.
|
||||||
|
func (h *Hash) GetBytes() []byte { |
||||||
|
return h.hash[:] |
||||||
|
} |
||||||
|
|
||||||
|
// SetHex sets the specified hex string as the hash value.
|
||||||
|
func (h *Hash) SetHex(hash string) error { |
||||||
|
hash = strings.ToLower(hash) |
||||||
|
if len(hash) >= 2 && hash[:2] == "0x" { |
||||||
|
hash = hash[2:] |
||||||
|
} |
||||||
|
if length := len(hash); length != 2*common.HashLength { |
||||||
|
return fmt.Errorf("invalid hash hex length: %v != %v", length, 2*common.HashLength) |
||||||
|
} |
||||||
|
bin, err := hex.DecodeString(hash) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
copy(h.hash[:], bin) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// GetHex retrieves the hex string representation of the hash.
|
||||||
|
func (h *Hash) GetHex() string { |
||||||
|
return h.hash.Hex() |
||||||
|
} |
||||||
|
|
||||||
|
// Hashes represents a slice of hashes.
|
||||||
|
type Hashes struct{ hashes []common.Hash } |
||||||
|
|
||||||
|
// Size returns the number of hashes in the slice.
|
||||||
|
func (h *Hashes) Size() int { |
||||||
|
return len(h.hashes) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the hash at the given index from the slice.
|
||||||
|
func (h *Hashes) Get(index int) (*Hash, error) { |
||||||
|
if index < 0 || index >= len(h.hashes) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Hash{h.hashes[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Address represents the 20 byte address of an Ethereum account.
|
||||||
|
type Address struct { |
||||||
|
address common.Address |
||||||
|
} |
||||||
|
|
||||||
|
// NewAddressFromBytes converts a slice of bytes to a hash value.
|
||||||
|
func NewAddressFromBytes(address []byte) (*Address, error) { |
||||||
|
a := new(Address) |
||||||
|
if err := a.SetBytes(address); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return a, nil |
||||||
|
} |
||||||
|
|
||||||
|
// NewAddressFromHex converts a hex string to a address value.
|
||||||
|
func NewAddressFromHex(address string) (*Address, error) { |
||||||
|
a := new(Address) |
||||||
|
if err := a.SetHex(address); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return a, nil |
||||||
|
} |
||||||
|
|
||||||
|
// SetBytes sets the specified slice of bytes as the address value.
|
||||||
|
func (a *Address) SetBytes(address []byte) error { |
||||||
|
if length := len(address); length != common.AddressLength { |
||||||
|
return fmt.Errorf("invalid address length: %v != %v", length, common.AddressLength) |
||||||
|
} |
||||||
|
copy(a.address[:], address) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// GetBytes retrieves the byte representation of the address.
|
||||||
|
func (a *Address) GetBytes() []byte { |
||||||
|
return a.address[:] |
||||||
|
} |
||||||
|
|
||||||
|
// SetHex sets the specified hex string as the address value.
|
||||||
|
func (a *Address) SetHex(address string) error { |
||||||
|
address = strings.ToLower(address) |
||||||
|
if len(address) >= 2 && address[:2] == "0x" { |
||||||
|
address = address[2:] |
||||||
|
} |
||||||
|
if length := len(address); length != 2*common.AddressLength { |
||||||
|
return fmt.Errorf("invalid address hex length: %v != %v", length, 2*common.AddressLength) |
||||||
|
} |
||||||
|
bin, err := hex.DecodeString(address) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
copy(a.address[:], bin) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// GetHex retrieves the hex string representation of the address.
|
||||||
|
func (a *Address) GetHex() string { |
||||||
|
return a.address.Hex() |
||||||
|
} |
||||||
|
|
||||||
|
// Addresses represents a slice of addresses.
|
||||||
|
type Addresses struct{ addresses []common.Address } |
||||||
|
|
||||||
|
// Size returns the number of addresses in the slice.
|
||||||
|
func (a *Addresses) Size() int { |
||||||
|
return len(a.addresses) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the address at the given index from the slice.
|
||||||
|
func (a *Addresses) Get(index int) (*Address, error) { |
||||||
|
if index < 0 || index >= len(a.addresses) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Address{a.addresses[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Set sets the address at the given index in the slice.
|
||||||
|
func (a *Addresses) Set(index int, address *Address) error { |
||||||
|
if index < 0 || index >= len(a.addresses) { |
||||||
|
return errors.New("index out of bounds") |
||||||
|
} |
||||||
|
a.addresses[index] = address.address |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the golang.org/x/net/context package to support
|
||||||
|
// client side context management on mobile platforms.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"time" |
||||||
|
|
||||||
|
"golang.org/x/net/context" |
||||||
|
) |
||||||
|
|
||||||
|
// Context carries a deadline, a cancelation signal, and other values across API
|
||||||
|
// boundaries.
|
||||||
|
type Context struct { |
||||||
|
context context.Context |
||||||
|
cancel context.CancelFunc |
||||||
|
} |
||||||
|
|
||||||
|
// NewContext returns a non-nil, empty Context. It is never canceled, has no
|
||||||
|
// values, and has no deadline. It is typically used by the main function,
|
||||||
|
// initialization, and tests, and as the top-level Context for incoming requests.
|
||||||
|
func NewContext() *Context { |
||||||
|
return &Context{ |
||||||
|
context: context.Background(), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// WithCancel returns a copy of the original context with cancellation mechanism
|
||||||
|
// included.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
|
func (c *Context) WithCancel() *Context { |
||||||
|
child, cancel := context.WithCancel(c.context) |
||||||
|
return &Context{ |
||||||
|
context: child, |
||||||
|
cancel: cancel, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// WithDeadline returns a copy of the original context with the deadline adjusted
|
||||||
|
// to be no later than the specified time.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
|
func (c *Context) WithDeadline(sec int64, nsec int64) *Context { |
||||||
|
child, cancel := context.WithDeadline(c.context, time.Unix(sec, nsec)) |
||||||
|
return &Context{ |
||||||
|
context: child, |
||||||
|
cancel: cancel, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// WithTimeout returns a copy of the original context with the deadline adjusted
|
||||||
|
// to be no later than now + the duration specified.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
|
func (c *Context) WithTimeout(nsec int64) *Context { |
||||||
|
child, cancel := context.WithTimeout(c.context, time.Duration(nsec)) |
||||||
|
return &Context{ |
||||||
|
context: child, |
||||||
|
cancel: cancel, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the core package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/ethereum/go-ethereum/core" |
||||||
|
"github.com/ethereum/go-ethereum/params" |
||||||
|
) |
||||||
|
|
||||||
|
// MainnetChainConfig is the chain configurations for the main Ethereum network.
|
||||||
|
var MainnetChainConfig = &ChainConfig{ |
||||||
|
HomesteadBlock: params.MainNetHomesteadBlock.Int64(), |
||||||
|
DAOForkBlock: params.MainNetDAOForkBlock.Int64(), |
||||||
|
DAOForkSupport: true, |
||||||
|
} |
||||||
|
|
||||||
|
// MainnetGenesis is the JSON spec to use for the main Ethereum network. It is
|
||||||
|
// actually empty since that defaults to the hard coded binary genesis block.
|
||||||
|
var MainnetGenesis = "" |
||||||
|
|
||||||
|
// TestnetChainConfig is the chain configurations for the Ethereum test network.
|
||||||
|
var TestnetChainConfig = &ChainConfig{ |
||||||
|
HomesteadBlock: params.TestNetHomesteadBlock.Int64(), |
||||||
|
DAOForkBlock: 0, |
||||||
|
DAOForkSupport: false, |
||||||
|
} |
||||||
|
|
||||||
|
// TestnetGenesis is the JSON spec to use for the Ethereum test network.
|
||||||
|
var TestnetGenesis = core.TestNetGenesisBlock() |
||||||
|
|
||||||
|
// ChainConfig is the core config which determines the blockchain settings.
|
||||||
|
type ChainConfig struct { |
||||||
|
HomesteadBlock int64 // Homestead switch block
|
||||||
|
DAOForkBlock int64 // TheDAO hard-fork switch block
|
||||||
|
DAOForkSupport bool // Whether the nodes supports or opposes the DAO hard-fork
|
||||||
|
} |
||||||
|
|
||||||
|
// NewChainConfig creates a new chain configuration that transitions immediately
|
||||||
|
// to homestead and has no notion of the DAO fork (ideal for a private network).
|
||||||
|
func NewChainConfig() *ChainConfig { |
||||||
|
return new(ChainConfig) |
||||||
|
} |
@ -0,0 +1,129 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the accounts package to support client side enode
|
||||||
|
// management on mobile platforms.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/cmd/utils" |
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover" |
||||||
|
) |
||||||
|
|
||||||
|
// MainnetBootnodes returns the enode URLs of the P2P bootstrap nodes running
|
||||||
|
// on the main network.
|
||||||
|
//
|
||||||
|
// Note, this needs to be a method to prevent gomobile generating a setter for it.
|
||||||
|
func MainnetBootnodes() *Enodes { |
||||||
|
nodes := &Enodes{nodes: make([]*discover.Node, len(utils.MainnetBootnodes))} |
||||||
|
for i, node := range utils.MainnetBootnodes { |
||||||
|
nodes.nodes[i] = node |
||||||
|
} |
||||||
|
return nodes |
||||||
|
} |
||||||
|
|
||||||
|
// TestnetBootnodes returns the enode URLs of the P2P bootstrap nodes running
|
||||||
|
// on the test network.
|
||||||
|
//
|
||||||
|
// Note, this needs to be a method to prevent gomobile generating a setter for it.
|
||||||
|
func TestnetBootnodes() *Enodes { |
||||||
|
nodes := &Enodes{nodes: make([]*discover.Node, len(utils.TestnetBootnodes))} |
||||||
|
for i, node := range utils.TestnetBootnodes { |
||||||
|
nodes.nodes[i] = node |
||||||
|
} |
||||||
|
return nodes |
||||||
|
} |
||||||
|
|
||||||
|
// Enode represents a host on the network.
|
||||||
|
type Enode struct { |
||||||
|
node *discover.Node |
||||||
|
} |
||||||
|
|
||||||
|
// NewEnode parses a node designator.
|
||||||
|
//
|
||||||
|
// There are two basic forms of node designators
|
||||||
|
// - incomplete nodes, which only have the public key (node ID)
|
||||||
|
// - complete nodes, which contain the public key and IP/Port information
|
||||||
|
//
|
||||||
|
// For incomplete nodes, the designator must look like one of these
|
||||||
|
//
|
||||||
|
// enode://<hex node id>
|
||||||
|
// <hex node id>
|
||||||
|
//
|
||||||
|
// For complete nodes, the node ID is encoded in the username portion
|
||||||
|
// of the URL, separated from the host by an @ sign. The hostname can
|
||||||
|
// only be given as an IP address, DNS domain names are not allowed.
|
||||||
|
// The port in the host name section is the TCP listening port. If the
|
||||||
|
// TCP and UDP (discovery) ports differ, the UDP port is specified as
|
||||||
|
// query parameter "discport".
|
||||||
|
//
|
||||||
|
// In the following example, the node URL describes
|
||||||
|
// a node with IP address 10.3.58.6, TCP listening port 30303
|
||||||
|
// and UDP discovery port 30301.
|
||||||
|
//
|
||||||
|
// enode://<hex node id>@10.3.58.6:30303?discport=30301
|
||||||
|
func NewEnode(rawurl string) (*Enode, error) { |
||||||
|
node, err := discover.ParseNode(rawurl) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &Enode{node}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Enodes represents a slice of accounts.
|
||||||
|
type Enodes struct{ nodes []*discover.Node } |
||||||
|
|
||||||
|
// NewEnodes creates a slice of uninitialized enodes.
|
||||||
|
func NewEnodes(size int) *Enodes { |
||||||
|
return &Enodes{ |
||||||
|
nodes: make([]*discover.Node, size), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// NewEnodesEmpty creates an empty slice of Enode values.
|
||||||
|
func NewEnodesEmpty() *Enodes { |
||||||
|
return NewEnodes(0) |
||||||
|
} |
||||||
|
|
||||||
|
// Size returns the number of enodes in the slice.
|
||||||
|
func (e *Enodes) Size() int { |
||||||
|
return len(e.nodes) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the enode at the given index from the slice.
|
||||||
|
func (e *Enodes) Get(index int) (*Enode, error) { |
||||||
|
if index < 0 || index >= len(e.nodes) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Enode{e.nodes[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Set sets the enode at the given index in the slice.
|
||||||
|
func (e *Enodes) Set(index int, enode *Enode) error { |
||||||
|
if index < 0 || index >= len(e.nodes) { |
||||||
|
return errors.New("index out of bounds") |
||||||
|
} |
||||||
|
e.nodes[index] = enode.node |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// Append adds a new enode element to the end of the slice.
|
||||||
|
func (e *Enodes) Append(enode *Enode) { |
||||||
|
e.nodes = append(e.nodes, enode.node) |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
// Copyright 2016 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 geth contains the simplified mobile APIs to go-ethereum.
|
||||||
|
//
|
||||||
|
// The scope of this package is *not* to allow writing a custom Ethereun client
|
||||||
|
// with pieces plucked from go-ethereum, rather to allow writing native dapps on
|
||||||
|
// mobile platforms. Keep this in mind when using or extending this package!
|
||||||
|
//
|
||||||
|
// API limitations
|
||||||
|
//
|
||||||
|
// Since gomobile cannot bridge arbitrary types between Go and Android/iOS, the
|
||||||
|
// exposed APIs need to be manually wrapped into simplified types, with custom
|
||||||
|
// constructors and getters/setters to ensure that they can be meaninfully used
|
||||||
|
// from Java/ObjC too.
|
||||||
|
//
|
||||||
|
// With this in mind, please try to limit the scope of this package and only add
|
||||||
|
// essentials without which mobile support cannot work, especially since manually
|
||||||
|
// syncing the code will be unwieldy otherwise. In the long term we might consider
|
||||||
|
// writing custom library generators, but those are out of scope now.
|
||||||
|
//
|
||||||
|
// Content wise each file in this package corresponds to an entire Go package
|
||||||
|
// from the go-ethereum repository. Please adhere to this scoping to prevent this
|
||||||
|
// package getting unmaintainable.
|
||||||
|
//
|
||||||
|
// Wrapping guidelines:
|
||||||
|
//
|
||||||
|
// Every type that is to be exposed should be wrapped into its own plain struct,
|
||||||
|
// which internally contains a single field: the original go-ethereum version.
|
||||||
|
// This is needed because gomobile cannot expose named types for now.
|
||||||
|
//
|
||||||
|
// Whenever a method argument or a return type is a custom struct, the pointer
|
||||||
|
// variant should always be used as value types crossing over between language
|
||||||
|
// boundaries might have strange behaviors.
|
||||||
|
//
|
||||||
|
// Slices of types should be converted into a single multiplicative type wrapping
|
||||||
|
// a go slice with the methods `Size`, `Get` and `Set`. Further slice operations
|
||||||
|
// should not be provided to limit the remote code complexity. Arrays should be
|
||||||
|
// avoided as much as possible since they complicate bounds checking.
|
||||||
|
//
|
||||||
|
// Note, a panic *cannot* cross over language boundaries, instead will result in
|
||||||
|
// an undebuggable SEGFAULT in the process. For error handling only ever use error
|
||||||
|
// returns, which may be the only or the second return.
|
||||||
|
package geth |
@ -0,0 +1,305 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains a wrapper for the Ethereum client.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"math/big" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types" |
||||||
|
"github.com/ethereum/go-ethereum/core/vm" |
||||||
|
"github.com/ethereum/go-ethereum/ethclient" |
||||||
|
) |
||||||
|
|
||||||
|
// EthereumClient provides access to the Ethereum APIs.
|
||||||
|
type EthereumClient struct { |
||||||
|
client *ethclient.Client |
||||||
|
} |
||||||
|
|
||||||
|
// NewEthereumClient connects a client to the given URL.
|
||||||
|
func NewEthereumClient(rawurl string) (*EthereumClient, error) { |
||||||
|
client, err := ethclient.Dial(rawurl) |
||||||
|
return &EthereumClient{client}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetBlockByHash returns the given full block.
|
||||||
|
func (ec *EthereumClient) GetBlockByHash(ctx *Context, hash *Hash) (*Block, error) { |
||||||
|
block, err := ec.client.BlockByHash(ctx.context, hash.hash) |
||||||
|
return &Block{block}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetBlockByNumber returns a block from the current canonical chain. If number is <0, the
|
||||||
|
// latest known block is returned.
|
||||||
|
func (ec *EthereumClient) GetBlockByNumber(ctx *Context, number int64) (*Block, error) { |
||||||
|
if number < 0 { |
||||||
|
block, err := ec.client.BlockByNumber(ctx.context, nil) |
||||||
|
return &Block{block}, err |
||||||
|
} |
||||||
|
block, err := ec.client.BlockByNumber(ctx.context, big.NewInt(number)) |
||||||
|
return &Block{block}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetHeaderByHash returns the block header with the given hash.
|
||||||
|
func (ec *EthereumClient) GetHeaderByHash(ctx *Context, hash *Hash) (*Header, error) { |
||||||
|
header, err := ec.client.HeaderByHash(ctx.context, hash.hash) |
||||||
|
return &Header{header}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetHeaderByNumber returns a block header from the current canonical chain. If number is <0,
|
||||||
|
// the latest known header is returned.
|
||||||
|
func (ec *EthereumClient) GetHeaderByNumber(ctx *Context, number int64) (*Header, error) { |
||||||
|
if number < 0 { |
||||||
|
header, err := ec.client.HeaderByNumber(ctx.context, nil) |
||||||
|
return &Header{header}, err |
||||||
|
} |
||||||
|
header, err := ec.client.HeaderByNumber(ctx.context, big.NewInt(number)) |
||||||
|
return &Header{header}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetTransactionByHash returns the transaction with the given hash.
|
||||||
|
func (ec *EthereumClient) GetTransactionByHash(ctx *Context, hash *Hash) (*Transaction, error) { |
||||||
|
tx, err := ec.client.TransactionByHash(ctx.context, hash.hash) |
||||||
|
return &Transaction{tx}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetTransactionCount returns the total number of transactions in the given block.
|
||||||
|
func (ec *EthereumClient) GetTransactionCount(ctx *Context, hash *Hash) (int, error) { |
||||||
|
count, err := ec.client.TransactionCount(ctx.context, hash.hash) |
||||||
|
return int(count), err |
||||||
|
} |
||||||
|
|
||||||
|
// GetTransactionInBlock returns a single transaction at index in the given block.
|
||||||
|
func (ec *EthereumClient) GetTransactionInBlock(ctx *Context, hash *Hash, index int) (*Transaction, error) { |
||||||
|
tx, err := ec.client.TransactionInBlock(ctx.context, hash.hash, uint(index)) |
||||||
|
return &Transaction{tx}, err |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// GetTransactionReceipt returns the receipt of a transaction by transaction hash.
|
||||||
|
// Note that the receipt is not available for pending transactions.
|
||||||
|
func (ec *EthereumClient) GetTransactionReceipt(ctx *Context, hash *Hash) (*Receipt, error) { |
||||||
|
receipt, err := ec.client.TransactionReceipt(ctx.context, hash.hash) |
||||||
|
return &Receipt{receipt}, err |
||||||
|
} |
||||||
|
|
||||||
|
// SyncProgress retrieves the current progress of the sync algorithm. If there's
|
||||||
|
// no sync currently running, it returns nil.
|
||||||
|
func (ec *EthereumClient) SyncProgress(ctx *Context) (*SyncProgress, error) { |
||||||
|
progress, err := ec.client.SyncProgress(ctx.context) |
||||||
|
if progress == nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &SyncProgress{*progress}, err |
||||||
|
} |
||||||
|
|
||||||
|
// NewHeadHandler is a client-side subscription callback to invoke on events and
|
||||||
|
// subscription failure.
|
||||||
|
type NewHeadHandler interface { |
||||||
|
OnNewHead(header *Header) |
||||||
|
OnError(failure string) |
||||||
|
} |
||||||
|
|
||||||
|
// SubscribeNewHead subscribes to notifications about the current blockchain head
|
||||||
|
// on the given channel.
|
||||||
|
func (ec *EthereumClient) SubscribeNewHead(ctx *Context, handler NewHeadHandler, buffer int) (*Subscription, error) { |
||||||
|
// Subscribe to the event internally
|
||||||
|
ch := make(chan *types.Header, buffer) |
||||||
|
sub, err := ec.client.SubscribeNewHead(ctx.context, ch) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
// Start up a dispatcher to feed into the callback
|
||||||
|
go func() { |
||||||
|
for { |
||||||
|
select { |
||||||
|
case header := <-ch: |
||||||
|
handler.OnNewHead(&Header{header}) |
||||||
|
|
||||||
|
case err := <-sub.Err(): |
||||||
|
handler.OnError(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
}() |
||||||
|
return &Subscription{sub}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// State Access
|
||||||
|
|
||||||
|
// GetBalanceAt returns the wei balance of the given account.
|
||||||
|
// The block number can be <0, in which case the balance is taken from the latest known block.
|
||||||
|
func (ec *EthereumClient) GetBalanceAt(ctx *Context, account *Address, number int64) (*BigInt, error) { |
||||||
|
if number < 0 { |
||||||
|
balance, err := ec.client.BalanceAt(ctx.context, account.address, nil) |
||||||
|
return &BigInt{balance}, err |
||||||
|
} |
||||||
|
balance, err := ec.client.BalanceAt(ctx.context, account.address, big.NewInt(number)) |
||||||
|
return &BigInt{balance}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetStorageAt returns the value of key in the contract storage of the given account.
|
||||||
|
// The block number can be <0, in which case the value is taken from the latest known block.
|
||||||
|
func (ec *EthereumClient) GetStorageAt(ctx *Context, account *Address, key *Hash, number int64) ([]byte, error) { |
||||||
|
if number < 0 { |
||||||
|
return ec.client.StorageAt(ctx.context, account.address, key.hash, nil) |
||||||
|
} |
||||||
|
return ec.client.StorageAt(ctx.context, account.address, key.hash, big.NewInt(number)) |
||||||
|
} |
||||||
|
|
||||||
|
// GetCodeAt returns the contract code of the given account.
|
||||||
|
// The block number can be <0, in which case the code is taken from the latest known block.
|
||||||
|
func (ec *EthereumClient) GetCodeAt(ctx *Context, account *Address, number int64) ([]byte, error) { |
||||||
|
if number < 0 { |
||||||
|
return ec.client.CodeAt(ctx.context, account.address, nil) |
||||||
|
} |
||||||
|
return ec.client.CodeAt(ctx.context, account.address, big.NewInt(number)) |
||||||
|
} |
||||||
|
|
||||||
|
// GetNonceAt returns the account nonce of the given account.
|
||||||
|
// The block number can be <0, in which case the nonce is taken from the latest known block.
|
||||||
|
func (ec *EthereumClient) GetNonceAt(ctx *Context, account *Address, number int64) (int64, error) { |
||||||
|
if number < 0 { |
||||||
|
nonce, err := ec.client.NonceAt(ctx.context, account.address, nil) |
||||||
|
return int64(nonce), err |
||||||
|
} |
||||||
|
nonce, err := ec.client.NonceAt(ctx.context, account.address, big.NewInt(number)) |
||||||
|
return int64(nonce), err |
||||||
|
} |
||||||
|
|
||||||
|
// Filters
|
||||||
|
|
||||||
|
// FilterLogs executes a filter query.
|
||||||
|
func (ec *EthereumClient) FilterLogs(ctx *Context, query *FilterQuery) (*Logs, error) { |
||||||
|
logs, err := ec.client.FilterLogs(ctx.context, query.query) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
// Temp hack due to vm.Logs being []*vm.Log
|
||||||
|
res := make(vm.Logs, len(logs)) |
||||||
|
for i, log := range logs { |
||||||
|
res[i] = &log |
||||||
|
} |
||||||
|
return &Logs{res}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// FilterLogsHandler is a client-side subscription callback to invoke on events and
|
||||||
|
// subscription failure.
|
||||||
|
type FilterLogsHandler interface { |
||||||
|
OnFilterLogs(log *Log) |
||||||
|
OnError(failure string) |
||||||
|
} |
||||||
|
|
||||||
|
// SubscribeFilterLogs subscribes to the results of a streaming filter query.
|
||||||
|
func (ec *EthereumClient) SubscribeFilterLogs(ctx *Context, query *FilterQuery, handler FilterLogsHandler, buffer int) (*Subscription, error) { |
||||||
|
// Subscribe to the event internally
|
||||||
|
ch := make(chan vm.Log, buffer) |
||||||
|
sub, err := ec.client.SubscribeFilterLogs(ctx.context, query.query, ch) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
// Start up a dispatcher to feed into the callback
|
||||||
|
go func() { |
||||||
|
for { |
||||||
|
select { |
||||||
|
case log := <-ch: |
||||||
|
handler.OnFilterLogs(&Log{&log}) |
||||||
|
|
||||||
|
case err := <-sub.Err(): |
||||||
|
handler.OnError(err.Error()) |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
}() |
||||||
|
return &Subscription{sub}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Pending State
|
||||||
|
|
||||||
|
// GetPendingBalanceAt returns the wei balance of the given account in the pending state.
|
||||||
|
func (ec *EthereumClient) GetPendingBalanceAt(ctx *Context, account *Address) (*BigInt, error) { |
||||||
|
balance, err := ec.client.PendingBalanceAt(ctx.context, account.address) |
||||||
|
return &BigInt{balance}, err |
||||||
|
} |
||||||
|
|
||||||
|
// GetPendingStorageAt returns the value of key in the contract storage of the given account in the pending state.
|
||||||
|
func (ec *EthereumClient) GetPendingStorageAt(ctx *Context, account *Address, key *Hash) ([]byte, error) { |
||||||
|
return ec.client.PendingStorageAt(ctx.context, account.address, key.hash) |
||||||
|
} |
||||||
|
|
||||||
|
// GetPendingCodeAt returns the contract code of the given account in the pending state.
|
||||||
|
func (ec *EthereumClient) GetPendingCodeAt(ctx *Context, account *Address) ([]byte, error) { |
||||||
|
return ec.client.PendingCodeAt(ctx.context, account.address) |
||||||
|
} |
||||||
|
|
||||||
|
// GetPendingNonceAt returns the account nonce of the given account in the pending state.
|
||||||
|
// This is the nonce that should be used for the next transaction.
|
||||||
|
func (ec *EthereumClient) GetPendingNonceAt(ctx *Context, account *Address) (int64, error) { |
||||||
|
nonce, err := ec.client.PendingNonceAt(ctx.context, account.address) |
||||||
|
return int64(nonce), err |
||||||
|
} |
||||||
|
|
||||||
|
// GetPendingTransactionCount returns the total number of transactions in the pending state.
|
||||||
|
func (ec *EthereumClient) GetPendingTransactionCount(ctx *Context) (int, error) { |
||||||
|
count, err := ec.client.PendingTransactionCount(ctx.context) |
||||||
|
return int(count), err |
||||||
|
} |
||||||
|
|
||||||
|
// Contract Calling
|
||||||
|
|
||||||
|
// CallContract executes a message call transaction, which is directly executed in the VM
|
||||||
|
// of the node, but never mined into the blockchain.
|
||||||
|
//
|
||||||
|
// blockNumber selects the block height at which the call runs. It can be <0, in which
|
||||||
|
// case the code is taken from the latest known block. Note that state from very old
|
||||||
|
// blocks might not be available.
|
||||||
|
func (ec *EthereumClient) CallContract(ctx *Context, msg *CallMsg, number int64) ([]byte, error) { |
||||||
|
if number < 0 { |
||||||
|
return ec.client.CallContract(ctx.context, msg.msg, nil) |
||||||
|
} |
||||||
|
return ec.client.CallContract(ctx.context, msg.msg, big.NewInt(number)) |
||||||
|
} |
||||||
|
|
||||||
|
// PendingCallContract executes a message call transaction using the EVM.
|
||||||
|
// The state seen by the contract call is the pending state.
|
||||||
|
func (ec *EthereumClient) PendingCallContract(ctx *Context, msg *CallMsg) ([]byte, error) { |
||||||
|
return ec.client.PendingCallContract(ctx.context, msg.msg) |
||||||
|
} |
||||||
|
|
||||||
|
// SuggestGasPrice retrieves the currently suggested gas price to allow a timely
|
||||||
|
// execution of a transaction.
|
||||||
|
func (ec *EthereumClient) SuggestGasPrice(ctx *Context) (*BigInt, error) { |
||||||
|
price, err := ec.client.SuggestGasPrice(ctx.context) |
||||||
|
return &BigInt{price}, err |
||||||
|
} |
||||||
|
|
||||||
|
// EstimateGas tries to estimate the gas needed to execute a specific transaction based on
|
||||||
|
// the current pending state of the backend blockchain. There is no guarantee that this is
|
||||||
|
// the true gas limit requirement as other transactions may be added or removed by miners,
|
||||||
|
// but it should provide a basis for setting a reasonable default.
|
||||||
|
func (ec *EthereumClient) EstimateGas(ctx *Context, msg *CallMsg) (*BigInt, error) { |
||||||
|
price, err := ec.client.EstimateGas(ctx.context, msg.msg) |
||||||
|
return &BigInt{price}, err |
||||||
|
} |
||||||
|
|
||||||
|
// SendTransaction injects a signed transaction into the pending pool for execution.
|
||||||
|
//
|
||||||
|
// If the transaction was a contract creation use the TransactionReceipt method to get the
|
||||||
|
// contract address after the transaction has been mined.
|
||||||
|
func (ec *EthereumClient) SendTransaction(ctx *Context, tx *Transaction) error { |
||||||
|
return ec.client.SendTransaction(ctx.context, tx.tx) |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the go-ethereum root package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"math/big" |
||||||
|
|
||||||
|
ethereum "github.com/ethereum/go-ethereum" |
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
) |
||||||
|
|
||||||
|
// Subscription represents an event subscription where events are
|
||||||
|
// delivered on a data channel.
|
||||||
|
type Subscription struct { |
||||||
|
sub ethereum.Subscription |
||||||
|
} |
||||||
|
|
||||||
|
// Unsubscribe cancels the sending of events to the data channel
|
||||||
|
// and closes the error channel.
|
||||||
|
func (s *Subscription) Unsubscribe() { |
||||||
|
s.sub.Unsubscribe() |
||||||
|
} |
||||||
|
|
||||||
|
// CallMsg contains parameters for contract calls.
|
||||||
|
type CallMsg struct { |
||||||
|
msg ethereum.CallMsg |
||||||
|
} |
||||||
|
|
||||||
|
// NewCallMsg creates an empty contract call parameter list.
|
||||||
|
func NewCallMsg() *CallMsg { |
||||||
|
return new(CallMsg) |
||||||
|
} |
||||||
|
|
||||||
|
func (msg *CallMsg) GetFrom() *Address { return &Address{msg.msg.From} } |
||||||
|
func (msg *CallMsg) GetGas() int64 { return msg.msg.Gas.Int64() } |
||||||
|
func (msg *CallMsg) GetGasPrice() *BigInt { return &BigInt{msg.msg.GasPrice} } |
||||||
|
func (msg *CallMsg) GetValue() *BigInt { return &BigInt{msg.msg.Value} } |
||||||
|
func (msg *CallMsg) GetData() []byte { return msg.msg.Data } |
||||||
|
func (msg *CallMsg) GetTo() *Address { |
||||||
|
if to := msg.msg.To; to != nil { |
||||||
|
return &Address{*msg.msg.To} |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func (msg *CallMsg) SetFrom(address *Address) { msg.msg.From = address.address } |
||||||
|
func (msg *CallMsg) SetGas(gas int64) { msg.msg.Gas = big.NewInt(gas) } |
||||||
|
func (msg *CallMsg) SetGasPrice(price *BigInt) { msg.msg.GasPrice = price.bigint } |
||||||
|
func (msg *CallMsg) SetValue(value *BigInt) { msg.msg.Value = value.bigint } |
||||||
|
func (msg *CallMsg) SetData(data []byte) { msg.msg.Data = data } |
||||||
|
func (msg *CallMsg) SetTo(address *Address) { |
||||||
|
if address == nil { |
||||||
|
msg.msg.To = nil |
||||||
|
} |
||||||
|
msg.msg.To = &address.address |
||||||
|
} |
||||||
|
|
||||||
|
// SyncProgress gives progress indications when the node is synchronising with
|
||||||
|
// the Ethereum network.
|
||||||
|
type SyncProgress struct { |
||||||
|
progress ethereum.SyncProgress |
||||||
|
} |
||||||
|
|
||||||
|
func (p *SyncProgress) GetStartingBlock() int64 { return int64(p.progress.StartingBlock) } |
||||||
|
func (p *SyncProgress) GetCurrentBlock() int64 { return int64(p.progress.CurrentBlock) } |
||||||
|
func (p *SyncProgress) GetHighestBlock() int64 { return int64(p.progress.HighestBlock) } |
||||||
|
func (p *SyncProgress) GetPulledStates() int64 { return int64(p.progress.PulledStates) } |
||||||
|
func (p *SyncProgress) GetKnownStates() int64 { return int64(p.progress.KnownStates) } |
||||||
|
|
||||||
|
// Topics is a set of topic lists to filter events with.
|
||||||
|
type Topics struct{ topics [][]common.Hash } |
||||||
|
|
||||||
|
// Size returns the number of topic lists inside the set
|
||||||
|
func (t *Topics) Size() int { |
||||||
|
return len(t.topics) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the topic list at the given index from the slice.
|
||||||
|
func (t *Topics) Get(index int) (*Hashes, error) { |
||||||
|
if index < 0 || index >= len(t.topics) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Hashes{t.topics[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Set sets the topic list at the given index in the slice.
|
||||||
|
func (t *Topics) Set(index int, topics *Hashes) error { |
||||||
|
if index < 0 || index >= len(t.topics) { |
||||||
|
return errors.New("index out of bounds") |
||||||
|
} |
||||||
|
t.topics[index] = topics.hashes |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// FilterQuery contains options for contact log filtering.
|
||||||
|
type FilterQuery struct { |
||||||
|
query ethereum.FilterQuery |
||||||
|
} |
||||||
|
|
||||||
|
// NewFilterQuery creates an empty filter query for contact log filtering.
|
||||||
|
func NewFilterQuery() *FilterQuery { |
||||||
|
return new(FilterQuery) |
||||||
|
} |
||||||
|
|
||||||
|
func (fq *FilterQuery) GetFromBlock() *BigInt { return &BigInt{fq.query.FromBlock} } |
||||||
|
func (fq *FilterQuery) GetToBlock() *BigInt { return &BigInt{fq.query.ToBlock} } |
||||||
|
func (fq *FilterQuery) GetAddresses() *Addresses { return &Addresses{fq.query.Addresses} } |
||||||
|
func (fq *FilterQuery) GetTopics() *Topics { return &Topics{fq.query.Topics} } |
@ -0,0 +1,188 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the node package to support client side node
|
||||||
|
// management on mobile platforms.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"math/big" |
||||||
|
"path/filepath" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/cmd/utils" |
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/core" |
||||||
|
"github.com/ethereum/go-ethereum/core/state" |
||||||
|
"github.com/ethereum/go-ethereum/eth" |
||||||
|
"github.com/ethereum/go-ethereum/ethclient" |
||||||
|
"github.com/ethereum/go-ethereum/node" |
||||||
|
"github.com/ethereum/go-ethereum/p2p/nat" |
||||||
|
"github.com/ethereum/go-ethereum/whisper" |
||||||
|
) |
||||||
|
|
||||||
|
// NodeConfig represents the collection of configuration values to fine tune the Geth
|
||||||
|
// node embedded into a mobile process. The available values are a subset of the
|
||||||
|
// entire API provided by go-ethereum to reduce the maintenance surface and dev
|
||||||
|
// complexity.
|
||||||
|
type NodeConfig struct { |
||||||
|
// Bootstrap nodes used to establish connectivity with the rest of the network.
|
||||||
|
BootstrapNodes *Enodes |
||||||
|
|
||||||
|
// MaxPeers is the maximum number of peers that can be connected. If this is
|
||||||
|
// set to zero, then only the configured static and trusted peers can connect.
|
||||||
|
MaxPeers int |
||||||
|
|
||||||
|
// EthereumEnabled specifies whether the node should run the Ethereum protocol.
|
||||||
|
EthereumEnabled bool |
||||||
|
|
||||||
|
// EthereumNetworkID is the network identifier used by the Ethereum protocol to
|
||||||
|
// decide if remote peers should be accepted or not.
|
||||||
|
EthereumNetworkID int |
||||||
|
|
||||||
|
// EthereumChainConfig is the default parameters of the blockchain to use. If no
|
||||||
|
// configuration is specified, it defaults to the main network.
|
||||||
|
EthereumChainConfig *ChainConfig |
||||||
|
|
||||||
|
// EthereumGenesis is the genesis JSON to use to seed the blockchain with. An
|
||||||
|
// empty genesis state is equivalent to using the mainnet's state.
|
||||||
|
EthereumGenesis string |
||||||
|
|
||||||
|
// EthereumTestnetNonces specifies whether to use account nonces from the testnet
|
||||||
|
// range (2^20) or from the mainnet one (0).
|
||||||
|
EthereumTestnetNonces bool |
||||||
|
|
||||||
|
// EthereumDatabaseCache is the system memory in MB to allocate for database caching.
|
||||||
|
// A minimum of 16MB is always reserved.
|
||||||
|
EthereumDatabaseCache int |
||||||
|
|
||||||
|
// WhisperEnabled specifies whether the node should run the Whisper protocol.
|
||||||
|
WhisperEnabled bool |
||||||
|
} |
||||||
|
|
||||||
|
// defaultNodeConfig contains the default node configuration values to use if all
|
||||||
|
// or some fields are missing from the user's specified list.
|
||||||
|
var defaultNodeConfig = &NodeConfig{ |
||||||
|
BootstrapNodes: MainnetBootnodes(), |
||||||
|
MaxPeers: 25, |
||||||
|
EthereumEnabled: true, |
||||||
|
EthereumNetworkID: 1, |
||||||
|
EthereumChainConfig: MainnetChainConfig, |
||||||
|
EthereumDatabaseCache: 16, |
||||||
|
} |
||||||
|
|
||||||
|
// NewNodeConfig creates a new node option set, initialized to the default values.
|
||||||
|
func NewNodeConfig() *NodeConfig { |
||||||
|
config := *defaultNodeConfig |
||||||
|
return &config |
||||||
|
} |
||||||
|
|
||||||
|
// Node represents a Geth Ethereum node instance.
|
||||||
|
type Node struct { |
||||||
|
node *node.Node |
||||||
|
} |
||||||
|
|
||||||
|
// NewNode creates and configures a new Geth node.
|
||||||
|
func NewNode(datadir string, config *NodeConfig) (*Node, error) { |
||||||
|
// If no or partial configurations were specified, use defaults
|
||||||
|
if config == nil { |
||||||
|
config = NewNodeConfig() |
||||||
|
} |
||||||
|
if config.MaxPeers == 0 { |
||||||
|
config.MaxPeers = defaultNodeConfig.MaxPeers |
||||||
|
} |
||||||
|
// Create the empty networking stack
|
||||||
|
nodeConf := &node.Config{ |
||||||
|
DataDir: datadir, |
||||||
|
KeyStoreDir: filepath.Join(datadir, "keystore"), // Mobile should never use internal keystores!
|
||||||
|
Name: common.MakeName(clientIdentifier, utils.Version), |
||||||
|
BootstrapNodes: config.BootstrapNodes.nodes, |
||||||
|
ListenAddr: ":0", |
||||||
|
NAT: nat.Any(), |
||||||
|
MaxPeers: config.MaxPeers, |
||||||
|
} |
||||||
|
stack, err := node.New(nodeConf) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
// Register the Ethereum protocol if requested
|
||||||
|
if config.EthereumEnabled { |
||||||
|
ethConf := ð.Config{ |
||||||
|
ChainConfig: &core.ChainConfig{ |
||||||
|
HomesteadBlock: big.NewInt(config.EthereumChainConfig.HomesteadBlock), |
||||||
|
DAOForkBlock: big.NewInt(config.EthereumChainConfig.DAOForkBlock), |
||||||
|
DAOForkSupport: config.EthereumChainConfig.DAOForkSupport, |
||||||
|
}, |
||||||
|
Genesis: config.EthereumGenesis, |
||||||
|
FastSync: true, |
||||||
|
DatabaseCache: config.EthereumDatabaseCache, |
||||||
|
NetworkId: config.EthereumNetworkID, |
||||||
|
GasPrice: new(big.Int).Mul(big.NewInt(20), common.Shannon), |
||||||
|
GpoMinGasPrice: new(big.Int).Mul(big.NewInt(20), common.Shannon), |
||||||
|
GpoMaxGasPrice: new(big.Int).Mul(big.NewInt(500), common.Shannon), |
||||||
|
GpoFullBlockRatio: 80, |
||||||
|
GpobaseStepDown: 10, |
||||||
|
GpobaseStepUp: 100, |
||||||
|
GpobaseCorrectionFactor: 110, |
||||||
|
} |
||||||
|
if config.EthereumTestnetNonces { |
||||||
|
state.StartingNonce = 1048576 // (2**20)
|
||||||
|
} |
||||||
|
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { |
||||||
|
return eth.New(ctx, ethConf) |
||||||
|
}); err != nil { |
||||||
|
return nil, fmt.Errorf("ethereum init: %v", err) |
||||||
|
} |
||||||
|
} |
||||||
|
// Register the Whisper protocol if requested
|
||||||
|
if config.WhisperEnabled { |
||||||
|
if err := stack.Register(func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil }); err != nil { |
||||||
|
return nil, fmt.Errorf("whisper init: %v", err) |
||||||
|
} |
||||||
|
} |
||||||
|
return &Node{stack}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Start creates a live P2P node and starts running it.
|
||||||
|
func (n *Node) Start() error { |
||||||
|
return n.node.Start() |
||||||
|
} |
||||||
|
|
||||||
|
// Stop terminates a running node along with all it's services. In the node was
|
||||||
|
// not started, an error is returned.
|
||||||
|
func (n *Node) Stop() error { |
||||||
|
return n.node.Stop() |
||||||
|
} |
||||||
|
|
||||||
|
// GetEthereumClient retrieves a client to access the Ethereum subsystem.
|
||||||
|
func (n *Node) GetEthereumClient() (*EthereumClient, error) { |
||||||
|
rpc, err := n.node.Attach() |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return &EthereumClient{ethclient.NewClient(rpc)}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// GetNodeInfo gathers and returns a collection of metadata known about the host.
|
||||||
|
func (n *Node) GetNodeInfo() *NodeInfo { |
||||||
|
return &NodeInfo{n.node.Server().NodeInfo()} |
||||||
|
} |
||||||
|
|
||||||
|
// GetPeersInfo returns an array of metadata objects describing connected peers.
|
||||||
|
func (n *Node) GetPeersInfo() *PeerInfos { |
||||||
|
return &PeerInfos{n.node.Server().PeersInfo()} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
// clientIdentifier is a hard coded identifier to report into the network.
|
||||||
|
var clientIdentifier = "GethDroid" |
@ -0,0 +1,22 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// +build ios
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
// clientIdentifier is a hard coded identifier to report into the network.
|
||||||
|
var clientIdentifier = "iGeth" |
@ -0,0 +1,22 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// +build !android,!ios
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
// clientIdentifier is a hard coded identifier to report into the network.
|
||||||
|
var clientIdentifier = "GethMobile" |
@ -0,0 +1,29 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains wrappers and init code for the logger.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/ethereum/go-ethereum/logger" |
||||||
|
"github.com/ethereum/go-ethereum/logger/glog" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
glog.SetV(logger.Info) |
||||||
|
glog.SetToStderr(true) |
||||||
|
} |
@ -0,0 +1,148 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains perverted wrappers to allow crossing over empty interfaces.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"math/big" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
) |
||||||
|
|
||||||
|
// Interface represents a wrapped version of Go's interface{}, with the capacity
|
||||||
|
// to store arbitrary data types.
|
||||||
|
//
|
||||||
|
// Since it's impossible to get the arbitrary-ness converted between Go and mobile
|
||||||
|
// platforms, we're using explicit getters and setters for the conversions. There
|
||||||
|
// is of course no point in enumerating everything, just enough to support the
|
||||||
|
// contract bindins requiring client side generated code.
|
||||||
|
type Interface struct { |
||||||
|
object interface{} |
||||||
|
} |
||||||
|
|
||||||
|
// NewInterface creates a new empty interface that can be used to pass around
|
||||||
|
// generic types.
|
||||||
|
func NewInterface() *Interface { |
||||||
|
return new(Interface) |
||||||
|
} |
||||||
|
|
||||||
|
func (i *Interface) SetBool(b bool) { i.object = &b } |
||||||
|
func (i *Interface) SetBools(bs []bool) { i.object = &bs } |
||||||
|
func (i *Interface) SetString(str string) { i.object = &str } |
||||||
|
func (i *Interface) SetStrings(strs *Strings) { i.object = &strs.strs } |
||||||
|
func (i *Interface) SetBinary(binary []byte) { i.object = &binary } |
||||||
|
func (i *Interface) SetBinaries(binaries [][]byte) { i.object = &binaries } |
||||||
|
func (i *Interface) SetAddress(address *Address) { i.object = &address.address } |
||||||
|
func (i *Interface) SetAddresses(addrs *Addresses) { i.object = &addrs.addresses } |
||||||
|
func (i *Interface) SetHash(hash *Hash) { i.object = &hash.hash } |
||||||
|
func (i *Interface) SetHashes(hashes *Hashes) { i.object = &hashes.hashes } |
||||||
|
func (i *Interface) SetInt8(n int8) { i.object = &n } |
||||||
|
func (i *Interface) SetInt16(n int16) { i.object = &n } |
||||||
|
func (i *Interface) SetInt32(n int32) { i.object = &n } |
||||||
|
func (i *Interface) SetInt64(n int64) { i.object = &n } |
||||||
|
func (i *Interface) SetUint8(bigint *BigInt) { n := uint8(bigint.bigint.Uint64()); i.object = &n } |
||||||
|
func (i *Interface) SetUint16(bigint *BigInt) { n := uint16(bigint.bigint.Uint64()); i.object = &n } |
||||||
|
func (i *Interface) SetUint32(bigint *BigInt) { n := uint32(bigint.bigint.Uint64()); i.object = &n } |
||||||
|
func (i *Interface) SetUint64(bigint *BigInt) { n := uint64(bigint.bigint.Uint64()); i.object = &n } |
||||||
|
func (i *Interface) SetBigInt(bigint *BigInt) { i.object = &bigint.bigint } |
||||||
|
func (i *Interface) SetBigInts(bigints *BigInts) { i.object = &bigints.bigints } |
||||||
|
|
||||||
|
func (i *Interface) SetDefaultBool() { i.object = new(bool) } |
||||||
|
func (i *Interface) SetDefaultBools() { i.object = new([]bool) } |
||||||
|
func (i *Interface) SetDefaultString() { i.object = new(string) } |
||||||
|
func (i *Interface) SetDefaultStrings() { i.object = new([]string) } |
||||||
|
func (i *Interface) SetDefaultBinary() { i.object = new([]byte) } |
||||||
|
func (i *Interface) SetDefaultBinaries() { i.object = new([][]byte) } |
||||||
|
func (i *Interface) SetDefaultAddress() { i.object = new(common.Address) } |
||||||
|
func (i *Interface) SetDefaultAddresses() { i.object = new([]common.Address) } |
||||||
|
func (i *Interface) SetDefaultHash() { i.object = new(common.Hash) } |
||||||
|
func (i *Interface) SetDefaultHashes() { i.object = new([]common.Hash) } |
||||||
|
func (i *Interface) SetDefaultInt8() { i.object = new(int8) } |
||||||
|
func (i *Interface) SetDefaultInt16() { i.object = new(int16) } |
||||||
|
func (i *Interface) SetDefaultInt32() { i.object = new(int32) } |
||||||
|
func (i *Interface) SetDefaultInt64() { i.object = new(int64) } |
||||||
|
func (i *Interface) SetDefaultUint8() { i.object = new(uint8) } |
||||||
|
func (i *Interface) SetDefaultUint16() { i.object = new(uint16) } |
||||||
|
func (i *Interface) SetDefaultUint32() { i.object = new(uint32) } |
||||||
|
func (i *Interface) SetDefaultUint64() { i.object = new(uint64) } |
||||||
|
func (i *Interface) SetDefaultBigInt() { i.object = new(*big.Int) } |
||||||
|
func (i *Interface) SetDefaultBigInts() { i.object = new([]*big.Int) } |
||||||
|
|
||||||
|
func (i *Interface) GetBool() bool { return *i.object.(*bool) } |
||||||
|
func (i *Interface) GetBools() []bool { return *i.object.(*[]bool) } |
||||||
|
func (i *Interface) GetString() string { return *i.object.(*string) } |
||||||
|
func (i *Interface) GetStrings() *Strings { return &Strings{*i.object.(*[]string)} } |
||||||
|
func (i *Interface) GetBinary() []byte { return *i.object.(*[]byte) } |
||||||
|
func (i *Interface) GetBinaries() [][]byte { return *i.object.(*[][]byte) } |
||||||
|
func (i *Interface) GetAddress() *Address { return &Address{*i.object.(*common.Address)} } |
||||||
|
func (i *Interface) GetAddresses() *Addresses { return &Addresses{*i.object.(*[]common.Address)} } |
||||||
|
func (i *Interface) GetHash() *Hash { return &Hash{*i.object.(*common.Hash)} } |
||||||
|
func (i *Interface) GetHashes() *Hashes { return &Hashes{*i.object.(*[]common.Hash)} } |
||||||
|
func (i *Interface) GetInt8() int8 { return *i.object.(*int8) } |
||||||
|
func (i *Interface) GetInt16() int16 { return *i.object.(*int16) } |
||||||
|
func (i *Interface) GetInt32() int32 { return *i.object.(*int32) } |
||||||
|
func (i *Interface) GetInt64() int64 { return *i.object.(*int64) } |
||||||
|
func (i *Interface) GetUint8() *BigInt { |
||||||
|
return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint8)))} |
||||||
|
} |
||||||
|
func (i *Interface) GetUint16() *BigInt { |
||||||
|
return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint16)))} |
||||||
|
} |
||||||
|
func (i *Interface) GetUint32() *BigInt { |
||||||
|
return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint32)))} |
||||||
|
} |
||||||
|
func (i *Interface) GetUint64() *BigInt { |
||||||
|
return &BigInt{new(big.Int).SetUint64(*i.object.(*uint64))} |
||||||
|
} |
||||||
|
func (i *Interface) GetBigInt() *BigInt { return &BigInt{*i.object.(**big.Int)} } |
||||||
|
func (i *Interface) GetBigInts() *BigInts { return &BigInts{*i.object.(*[]*big.Int)} } |
||||||
|
|
||||||
|
// Interfaces is a slices of wrapped generic objects.
|
||||||
|
type Interfaces struct { |
||||||
|
objects []interface{} |
||||||
|
} |
||||||
|
|
||||||
|
// NewInterfaces creates a slice of uninitialized interfaces.
|
||||||
|
func NewInterfaces(size int) *Interfaces { |
||||||
|
return &Interfaces{ |
||||||
|
objects: make([]interface{}, size), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Size returns the number of interfaces in the slice.
|
||||||
|
func (i *Interfaces) Size() int { |
||||||
|
return len(i.objects) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the bigint at the given index from the slice.
|
||||||
|
func (i *Interfaces) Get(index int) (*Interface, error) { |
||||||
|
if index < 0 || index >= len(i.objects) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Interface{i.objects[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Set sets the big int at the given index in the slice.
|
||||||
|
func (i *Interfaces) Set(index int, object *Interface) error { |
||||||
|
if index < 0 || index >= len(i.objects) { |
||||||
|
return errors.New("index out of bounds") |
||||||
|
} |
||||||
|
i.objects[index] = object.object |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
// Copyright 2016 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 pi copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Contains wrappers for the p2p package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/p2p" |
||||||
|
) |
||||||
|
|
||||||
|
// NodeInfo represents pi short summary of the information known about the host.
|
||||||
|
type NodeInfo struct { |
||||||
|
info *p2p.NodeInfo |
||||||
|
} |
||||||
|
|
||||||
|
func (ni *NodeInfo) GetID() string { return ni.info.ID } |
||||||
|
func (ni *NodeInfo) GetName() string { return ni.info.Name } |
||||||
|
func (ni *NodeInfo) GetEnode() string { return ni.info.Enode } |
||||||
|
func (ni *NodeInfo) GetIP() string { return ni.info.IP } |
||||||
|
func (ni *NodeInfo) GetDiscoveryPort() int { return ni.info.Ports.Discovery } |
||||||
|
func (ni *NodeInfo) GetListenerPort() int { return ni.info.Ports.Listener } |
||||||
|
func (ni *NodeInfo) GetListenerAddress() string { return ni.info.ListenAddr } |
||||||
|
func (ni *NodeInfo) GetProtocols() *Strings { |
||||||
|
protos := []string{} |
||||||
|
for proto, _ := range ni.info.Protocols { |
||||||
|
protos = append(protos, proto) |
||||||
|
} |
||||||
|
return &Strings{protos} |
||||||
|
} |
||||||
|
|
||||||
|
// PeerInfo represents pi short summary of the information known about pi connected peer.
|
||||||
|
type PeerInfo struct { |
||||||
|
info *p2p.PeerInfo |
||||||
|
} |
||||||
|
|
||||||
|
func (pi *PeerInfo) GetID() string { return pi.info.ID } |
||||||
|
func (pi *PeerInfo) GetName() string { return pi.info.Name } |
||||||
|
func (pi *PeerInfo) GetCaps() *Strings { return &Strings{pi.info.Caps} } |
||||||
|
func (pi *PeerInfo) GetLocalAddress() string { return pi.info.Network.LocalAddress } |
||||||
|
func (pi *PeerInfo) GetRemoteAddress() string { return pi.info.Network.RemoteAddress } |
||||||
|
|
||||||
|
// PeerInfos represents a slice of infos about remote peers.
|
||||||
|
type PeerInfos struct { |
||||||
|
infos []*p2p.PeerInfo |
||||||
|
} |
||||||
|
|
||||||
|
// Size returns the number of peer info entries in the slice.
|
||||||
|
func (pi *PeerInfos) Size() int { |
||||||
|
return len(pi.infos) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the peer info at the given index from the slice.
|
||||||
|
func (pi *PeerInfos) Get(index int) (*PeerInfo, error) { |
||||||
|
if index < 0 || index >= len(pi.infos) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &PeerInfo{pi.infos[index]}, nil |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
// Copyright 2016 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 s copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Contains various wrappers for primitive types.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
) |
||||||
|
|
||||||
|
// Strings represents s slice of strs.
|
||||||
|
type Strings struct{ strs []string } |
||||||
|
|
||||||
|
// Size returns the number of strs in the slice.
|
||||||
|
func (s *Strings) Size() int { |
||||||
|
return len(s.strs) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the string at the given index from the slice.
|
||||||
|
func (s *Strings) Get(index int) (string, error) { |
||||||
|
if index < 0 || index >= len(s.strs) { |
||||||
|
return "", errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return s.strs[index], nil |
||||||
|
} |
||||||
|
|
||||||
|
// Set sets the string at the given index in the slice.
|
||||||
|
func (s *Strings) Set(index int, str string) error { |
||||||
|
if index < 0 || index >= len(s.strs) { |
||||||
|
return errors.New("index out of bounds") |
||||||
|
} |
||||||
|
s.strs[index] = str |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// String implements the Stringer interface.
|
||||||
|
func (s *Strings) String() string { |
||||||
|
return fmt.Sprintf("%v", s.strs) |
||||||
|
} |
@ -0,0 +1,189 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the core/types package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types" |
||||||
|
) |
||||||
|
|
||||||
|
// A Nonce is a 64-bit hash which proves (combined with the mix-hash) that
|
||||||
|
// a sufficient amount of computation has been carried out on a block.
|
||||||
|
type Nonce struct { |
||||||
|
nonce types.BlockNonce |
||||||
|
} |
||||||
|
|
||||||
|
// GetBytes retrieves the byte representation of the block nonce.
|
||||||
|
func (n *Nonce) GetBytes() []byte { |
||||||
|
return n.nonce[:] |
||||||
|
} |
||||||
|
|
||||||
|
// GetHex retrieves the hex string representation of the block nonce.
|
||||||
|
func (n *Nonce) GetHex() string { |
||||||
|
return fmt.Sprintf("0x%x", n.nonce[:]) |
||||||
|
} |
||||||
|
|
||||||
|
// Bloom represents a 256 bit bloom filter.
|
||||||
|
type Bloom struct { |
||||||
|
bloom types.Bloom |
||||||
|
} |
||||||
|
|
||||||
|
// GetBytes retrieves the byte representation of the bloom filter.
|
||||||
|
func (b *Bloom) GetBytes() []byte { |
||||||
|
return b.bloom[:] |
||||||
|
} |
||||||
|
|
||||||
|
// GetHex retrieves the hex string representation of the bloom filter.
|
||||||
|
func (b *Bloom) GetHex() string { |
||||||
|
return fmt.Sprintf("0x%x", b.bloom[:]) |
||||||
|
} |
||||||
|
|
||||||
|
// Header represents a block header in the Ethereum blockchain.
|
||||||
|
type Header struct { |
||||||
|
header *types.Header |
||||||
|
} |
||||||
|
|
||||||
|
func (h *Header) GetParentHash() *Hash { return &Hash{h.header.ParentHash} } |
||||||
|
func (h *Header) GetUncleHash() *Hash { return &Hash{h.header.UncleHash} } |
||||||
|
func (h *Header) GetCoinbase() *Address { return &Address{h.header.Coinbase} } |
||||||
|
func (h *Header) GetRoot() *Hash { return &Hash{h.header.Root} } |
||||||
|
func (h *Header) GetTxHash() *Hash { return &Hash{h.header.TxHash} } |
||||||
|
func (h *Header) GetReceiptHash() *Hash { return &Hash{h.header.ReceiptHash} } |
||||||
|
func (h *Header) GetBloom() *Bloom { return &Bloom{h.header.Bloom} } |
||||||
|
func (h *Header) GetDifficulty() *BigInt { return &BigInt{h.header.Difficulty} } |
||||||
|
func (h *Header) GetNumber() int64 { return h.header.Number.Int64() } |
||||||
|
func (h *Header) GetGasLimit() int64 { return h.header.GasLimit.Int64() } |
||||||
|
func (h *Header) GetGasUsed() int64 { return h.header.GasUsed.Int64() } |
||||||
|
func (h *Header) GetTime() int64 { return h.header.Time.Int64() } |
||||||
|
func (h *Header) GetExtra() []byte { return h.header.Extra } |
||||||
|
func (h *Header) GetMixDigest() *Hash { return &Hash{h.header.MixDigest} } |
||||||
|
func (h *Header) GetNonce() *Nonce { return &Nonce{h.header.Nonce} } |
||||||
|
|
||||||
|
func (h *Header) GetHash() *Hash { return &Hash{h.header.Hash()} } |
||||||
|
func (h *Header) GetHashNoNonce() *Hash { return &Hash{h.header.HashNoNonce()} } |
||||||
|
|
||||||
|
// Headers represents a slice of headers.
|
||||||
|
type Headers struct{ headers []*types.Header } |
||||||
|
|
||||||
|
// Size returns the number of headers in the slice.
|
||||||
|
func (h *Headers) Size() int { |
||||||
|
return len(h.headers) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the header at the given index from the slice.
|
||||||
|
func (h *Headers) Get(index int) (*Header, error) { |
||||||
|
if index < 0 || index >= len(h.headers) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Header{h.headers[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Block represents an entire block in the Ethereum blockchain.
|
||||||
|
type Block struct { |
||||||
|
block *types.Block |
||||||
|
} |
||||||
|
|
||||||
|
func (b *Block) GetParentHash() *Hash { return &Hash{b.block.ParentHash()} } |
||||||
|
func (b *Block) GetUncleHash() *Hash { return &Hash{b.block.UncleHash()} } |
||||||
|
func (b *Block) GetCoinbase() *Address { return &Address{b.block.Coinbase()} } |
||||||
|
func (b *Block) GetRoot() *Hash { return &Hash{b.block.Root()} } |
||||||
|
func (b *Block) GetTxHash() *Hash { return &Hash{b.block.TxHash()} } |
||||||
|
func (b *Block) GetReceiptHash() *Hash { return &Hash{b.block.ReceiptHash()} } |
||||||
|
func (b *Block) GetBloom() *Bloom { return &Bloom{b.block.Bloom()} } |
||||||
|
func (b *Block) GetDifficulty() *BigInt { return &BigInt{b.block.Difficulty()} } |
||||||
|
func (b *Block) GetNumber() int64 { return b.block.Number().Int64() } |
||||||
|
func (b *Block) GetGasLimit() int64 { return b.block.GasLimit().Int64() } |
||||||
|
func (b *Block) GetGasUsed() int64 { return b.block.GasUsed().Int64() } |
||||||
|
func (b *Block) GetTime() int64 { return b.block.Time().Int64() } |
||||||
|
func (b *Block) GetExtra() []byte { return b.block.Extra() } |
||||||
|
func (b *Block) GetMixDigest() *Hash { return &Hash{b.block.MixDigest()} } |
||||||
|
func (b *Block) GetNonce() int64 { return int64(b.block.Nonce()) } |
||||||
|
|
||||||
|
func (b *Block) GetHash() *Hash { return &Hash{b.block.Hash()} } |
||||||
|
func (b *Block) GetHashNoNonce() *Hash { return &Hash{b.block.HashNoNonce()} } |
||||||
|
|
||||||
|
func (b *Block) GetHeader() *Header { return &Header{b.block.Header()} } |
||||||
|
func (b *Block) GetUncles() *Headers { return &Headers{b.block.Uncles()} } |
||||||
|
func (b *Block) GetTransactions() *Transactions { return &Transactions{b.block.Transactions()} } |
||||||
|
func (b *Block) GetTransaction(hash *Hash) *Transaction { |
||||||
|
return &Transaction{b.block.Transaction(hash.hash)} |
||||||
|
} |
||||||
|
|
||||||
|
// Transaction represents a single Ethereum transaction.
|
||||||
|
type Transaction struct { |
||||||
|
tx *types.Transaction |
||||||
|
} |
||||||
|
|
||||||
|
func (tx *Transaction) GetData() []byte { return tx.tx.Data() } |
||||||
|
func (tx *Transaction) GetGas() int64 { return tx.tx.Gas().Int64() } |
||||||
|
func (tx *Transaction) GetGasPrice() *BigInt { return &BigInt{tx.tx.GasPrice()} } |
||||||
|
func (tx *Transaction) GetValue() *BigInt { return &BigInt{tx.tx.Value()} } |
||||||
|
func (tx *Transaction) GetNonce() int64 { return int64(tx.tx.Nonce()) } |
||||||
|
|
||||||
|
func (tx *Transaction) GetHash() *Hash { return &Hash{tx.tx.Hash()} } |
||||||
|
func (tx *Transaction) GetSigHash() *Hash { return &Hash{tx.tx.SigHash()} } |
||||||
|
func (tx *Transaction) GetCost() *BigInt { return &BigInt{tx.tx.Cost()} } |
||||||
|
|
||||||
|
func (tx *Transaction) GetFrom() (*Address, error) { |
||||||
|
from, err := tx.tx.From() |
||||||
|
return &Address{from}, err |
||||||
|
} |
||||||
|
|
||||||
|
func (tx *Transaction) GetTo() *Address { |
||||||
|
if to := tx.tx.To(); to != nil { |
||||||
|
return &Address{*to} |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func (tx *Transaction) WithSignature(sig []byte) (*Transaction, error) { |
||||||
|
t, err := tx.tx.WithSignature(sig) |
||||||
|
return &Transaction{t}, err |
||||||
|
} |
||||||
|
|
||||||
|
// Transactions represents a slice of transactions.
|
||||||
|
type Transactions struct{ txs types.Transactions } |
||||||
|
|
||||||
|
// Size returns the number of transactions in the slice.
|
||||||
|
func (t *Transactions) Size() int { |
||||||
|
return len(t.txs) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the transaction at the given index from the slice.
|
||||||
|
func (t *Transactions) Get(index int) (*Transaction, error) { |
||||||
|
if index < 0 || index >= len(t.txs) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Transaction{t.txs[index]}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Receipt represents the results of a transaction.
|
||||||
|
type Receipt struct { |
||||||
|
receipt *types.Receipt |
||||||
|
} |
||||||
|
|
||||||
|
func (r *Receipt) GetPostState() []byte { return r.receipt.PostState } |
||||||
|
func (r *Receipt) GetCumulativeGasUsed() *BigInt { return &BigInt{r.receipt.CumulativeGasUsed} } |
||||||
|
func (r *Receipt) GetBloom() *Bloom { return &Bloom{r.receipt.Bloom} } |
||||||
|
func (r *Receipt) GetLogs() *Logs { return &Logs{r.receipt.Logs} } |
||||||
|
func (r *Receipt) GetTxHash() *Hash { return &Hash{r.receipt.TxHash} } |
||||||
|
func (r *Receipt) GetContractAddress() *Address { return &Address{r.receipt.ContractAddress} } |
||||||
|
func (r *Receipt) GetGasUsed() *BigInt { return &BigInt{r.receipt.GasUsed} } |
@ -0,0 +1,56 @@ |
|||||||
|
// Copyright 2016 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/>.
|
||||||
|
|
||||||
|
// Contains all the wrappers from the core/types package.
|
||||||
|
|
||||||
|
package geth |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm" |
||||||
|
) |
||||||
|
|
||||||
|
// Log represents a contract log event. These events are generated by the LOG
|
||||||
|
// opcode and stored/indexed by the node.
|
||||||
|
type Log struct { |
||||||
|
log *vm.Log |
||||||
|
} |
||||||
|
|
||||||
|
func (l *Log) GetAddress() *Address { return &Address{l.log.Address} } |
||||||
|
func (l *Log) GetTopics() *Hashes { return &Hashes{l.log.Topics} } |
||||||
|
func (l *Log) GetData() []byte { return l.log.Data } |
||||||
|
func (l *Log) GetBlockNumber() int64 { return int64(l.log.BlockNumber) } |
||||||
|
func (l *Log) GetTxHash() *Hash { return &Hash{l.log.TxHash} } |
||||||
|
func (l *Log) GetTxIndex() int { return int(l.log.TxIndex) } |
||||||
|
func (l *Log) GetBlockHash() *Hash { return &Hash{l.log.BlockHash} } |
||||||
|
func (l *Log) GetIndex() int { return int(l.log.Index) } |
||||||
|
|
||||||
|
// Logs represents a slice of VM logs.
|
||||||
|
type Logs struct{ logs vm.Logs } |
||||||
|
|
||||||
|
// Size returns the number of logs in the slice.
|
||||||
|
func (l *Logs) Size() int { |
||||||
|
return len(l.logs) |
||||||
|
} |
||||||
|
|
||||||
|
// Get returns the log at the given index from the slice.
|
||||||
|
func (l *Logs) Get(index int) (*Log, error) { |
||||||
|
if index < 0 || index >= len(l.logs) { |
||||||
|
return nil, errors.New("index out of bounds") |
||||||
|
} |
||||||
|
return &Log{l.logs[index]}, nil |
||||||
|
} |
Loading…
Reference in new issue