github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/mobile/bind.go (about) 1 // Copyright 2016 The Spectrum Authors 2 // This file is part of the Spectrum library. 3 // 4 // The Spectrum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The Spectrum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the Spectrum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Contains all the wrappers from the bind package. 18 19 package geth 20 21 import ( 22 "math/big" 23 "strings" 24 25 "github.com/SmartMeshFoundation/Spectrum/accounts/abi" 26 "github.com/SmartMeshFoundation/Spectrum/accounts/abi/bind" 27 "github.com/SmartMeshFoundation/Spectrum/common" 28 "github.com/SmartMeshFoundation/Spectrum/core/types" 29 ) 30 31 // Signer is an interaface defining the callback when a contract requires a 32 // method to sign the transaction before submission. 33 type Signer interface { 34 Sign(*Address, *Transaction) (tx *Transaction, _ error) 35 } 36 37 type signer struct { 38 sign bind.SignerFn 39 } 40 41 func (s *signer) Sign(addr *Address, unsignedTx *Transaction) (signedTx *Transaction, _ error) { 42 sig, err := s.sign(types.HomesteadSigner{}, addr.address, unsignedTx.tx) 43 if err != nil { 44 return nil, err 45 } 46 return &Transaction{sig}, nil 47 } 48 49 // CallOpts is the collection of options to fine tune a contract call request. 50 type CallOpts struct { 51 opts bind.CallOpts 52 } 53 54 // NewCallOpts creates a new option set for contract calls. 55 func NewCallOpts() *CallOpts { 56 return new(CallOpts) 57 } 58 59 func (opts *CallOpts) IsPending() bool { return opts.opts.Pending } 60 func (opts *CallOpts) GetGasLimit() int64 { return 0 /* TODO(karalabe) */ } 61 62 // GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) 63 // Even then it's awkward to unpack the subtleties of a Go context out to Java. 64 // func (opts *CallOpts) GetContext() *Context { return &Context{opts.opts.Context} } 65 66 func (opts *CallOpts) SetPending(pending bool) { opts.opts.Pending = pending } 67 func (opts *CallOpts) SetGasLimit(limit int64) { /* TODO(karalabe) */ } 68 func (opts *CallOpts) SetContext(context *Context) { opts.opts.Context = context.context } 69 70 // TransactOpts is the collection of authorization data required to create a 71 // valid Ethereum transaction. 72 type TransactOpts struct { 73 opts bind.TransactOpts 74 } 75 76 func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From} } 77 func (opts *TransactOpts) GetNonce() int64 { return opts.opts.Nonce.Int64() } 78 func (opts *TransactOpts) GetValue() *BigInt { return &BigInt{opts.opts.Value} } 79 func (opts *TransactOpts) GetGasPrice() *BigInt { return &BigInt{opts.opts.GasPrice} } 80 func (opts *TransactOpts) GetGasLimit() int64 { return opts.opts.GasLimit.Int64() } 81 82 // GetSigner cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) 83 // func (opts *TransactOpts) GetSigner() Signer { return &signer{opts.opts.Signer} } 84 85 // GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) 86 // Even then it's awkward to unpack the subtleties of a Go context out to Java. 87 //func (opts *TransactOpts) GetContext() *Context { return &Context{opts.opts.Context} } 88 89 func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address } 90 func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) } 91 func (opts *TransactOpts) SetSigner(s Signer) { 92 opts.opts.Signer = func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 93 sig, err := s.Sign(&Address{addr}, &Transaction{tx}) 94 if err != nil { 95 return nil, err 96 } 97 return sig.tx, nil 98 } 99 } 100 func (opts *TransactOpts) SetValue(value *BigInt) { opts.opts.Value = value.bigint } 101 func (opts *TransactOpts) SetGasPrice(price *BigInt) { opts.opts.GasPrice = price.bigint } 102 func (opts *TransactOpts) SetGasLimit(limit int64) { opts.opts.GasLimit = big.NewInt(limit) } 103 func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context } 104 105 // BoundContract is the base wrapper object that reflects a contract on the 106 // Ethereum network. It contains a collection of methods that are used by the 107 // higher level contract bindings to operate. 108 type BoundContract struct { 109 contract *bind.BoundContract 110 address common.Address 111 deployer *types.Transaction 112 } 113 114 // DeployContract deploys a contract onto the Ethereum blockchain and binds the 115 // deployment address with a wrapper. 116 func DeployContract(opts *TransactOpts, abiJSON string, bytecode []byte, client *EthereumClient, args *Interfaces) (contract *BoundContract, _ error) { 117 // Deploy the contract to the network 118 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 119 if err != nil { 120 return nil, err 121 } 122 addr, tx, bound, err := bind.DeployContract(&opts.opts, parsed, common.CopyBytes(bytecode), client.client, args.objects...) 123 if err != nil { 124 return nil, err 125 } 126 return &BoundContract{ 127 contract: bound, 128 address: addr, 129 deployer: tx, 130 }, nil 131 } 132 133 // BindContract creates a low level contract interface through which calls and 134 // transactions may be made through. 135 func BindContract(address *Address, abiJSON string, client *EthereumClient) (contract *BoundContract, _ error) { 136 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 137 if err != nil { 138 return nil, err 139 } 140 return &BoundContract{ 141 contract: bind.NewBoundContract(address.address, parsed, client.client, client.client), 142 address: address.address, 143 }, nil 144 } 145 146 func (c *BoundContract) GetAddress() *Address { return &Address{c.address} } 147 func (c *BoundContract) GetDeployer() *Transaction { 148 if c.deployer == nil { 149 return nil 150 } 151 return &Transaction{c.deployer} 152 } 153 154 // Call invokes the (constant) contract method with params as input values and 155 // sets the output to result. 156 func (c *BoundContract) Call(opts *CallOpts, out *Interfaces, method string, args *Interfaces) error { 157 results := make([]interface{}, len(out.objects)) 158 copy(results, out.objects) 159 if err := c.contract.Call(&opts.opts, &results, method, args.objects...); err != nil { 160 return err 161 } 162 copy(out.objects, results) 163 return nil 164 } 165 166 // Transact invokes the (paid) contract method with params as input values. 167 func (c *BoundContract) Transact(opts *TransactOpts, method string, args *Interfaces) (tx *Transaction, _ error) { 168 rawTx, err := c.contract.Transact(&opts.opts, method, args.objects...) 169 if err != nil { 170 return nil, err 171 } 172 return &Transaction{rawTx}, nil 173 } 174 175 // Transfer initiates a plain transaction to move funds to the contract, calling 176 // its default method if one is available. 177 func (c *BoundContract) Transfer(opts *TransactOpts) (tx *Transaction, _ error) { 178 rawTx, err := c.contract.Transfer(&opts.opts) 179 if err != nil { 180 return nil, err 181 } 182 return &Transaction{rawTx}, nil 183 }