github.com/core-coin/go-core/v2@v2.1.9/mobile/bind.go (about) 1 // Copyright 2016 by the Authors 2 // This file is part of the go-core library. 3 // 4 // The go-core 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 go-core 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 go-core library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Contains all the wrappers from the bind package. 18 19 package gocore 20 21 import ( 22 "math/big" 23 "strings" 24 25 "github.com/core-coin/go-core/v2/accounts/abi" 26 "github.com/core-coin/go-core/v2/accounts/abi/bind" 27 "github.com/core-coin/go-core/v2/accounts/keystore" 28 "github.com/core-coin/go-core/v2/common" 29 "github.com/core-coin/go-core/v2/core/types" 30 ) 31 32 // Signer is an interface defining the callback when a contract requires a 33 // method to sign the transaction before submission. 34 type Signer interface { 35 Sign(addr *Address, unsignedTx *Transaction) (tx *Transaction, _ error) 36 } 37 38 type MobileSigner struct { 39 sign bind.SignerFn 40 } 41 42 func (s *MobileSigner) Sign(addr *Address, unsignedTx *Transaction) (signedTx *Transaction, _ error) { 43 sig, err := s.sign(addr.address, unsignedTx.tx) 44 if err != nil { 45 return nil, err 46 } 47 return &Transaction{sig}, nil 48 } 49 50 // CallOpts is the collection of options to fine tune a contract call request. 51 type CallOpts struct { 52 opts bind.CallOpts 53 } 54 55 // NewCallOpts creates a new option set for contract calls. 56 func NewCallOpts() *CallOpts { 57 return new(CallOpts) 58 } 59 60 func (opts *CallOpts) IsPending() bool { return opts.opts.Pending } 61 func (opts *CallOpts) GetEnergyLimit() int64 { return 0 /* TODO(raisty) */ } 62 63 // GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) 64 // Even then it's awkward to unpack the subtleties of a Go context out to Java. 65 // func (opts *CallOpts) GetContext() *Context { return &Context{opts.opts.Context} } 66 67 func (opts *CallOpts) SetPending(pending bool) { opts.opts.Pending = pending } 68 func (opts *CallOpts) SetEnergyLimit(limit int64) { /* TODO(raisty) */ } 69 func (opts *CallOpts) SetContext(context *Context) { opts.opts.Context = context.context } 70 func (opts *CallOpts) SetFrom(addr *Address) { opts.opts.From = addr.address } 71 72 // TransactOpts is the collection of authorization data required to create a 73 // valid Core transaction. 74 type TransactOpts struct { 75 opts bind.TransactOpts 76 } 77 78 // NewTransactOpts creates a new option set for contract transaction. 79 func NewTransactOpts() *TransactOpts { 80 return new(TransactOpts) 81 } 82 83 // NewKeyedTransactOpts is a utility method to easily create a transaction signer 84 // from a single private key. 85 func NewKeyedTransactOpts(keyJson []byte, passphrase string, networkID *big.Int) (*TransactOpts, error) { 86 key, err := keystore.DecryptKey(keyJson, passphrase) 87 if err != nil { 88 return nil, err 89 } 90 auth, err := bind.NewKeyedTransactorWithNetworkID(key.PrivateKey, networkID) 91 if err != nil { 92 return nil, err 93 } 94 return &TransactOpts{*auth}, nil 95 } 96 97 func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From} } 98 func (opts *TransactOpts) GetNonce() int64 { return opts.opts.Nonce.Int64() } 99 func (opts *TransactOpts) GetValue() *BigInt { return &BigInt{opts.opts.Value} } 100 func (opts *TransactOpts) GetEnergyPrice() *BigInt { return &BigInt{opts.opts.EnergyPrice} } 101 func (opts *TransactOpts) GetEnergyLimit() int64 { return int64(opts.opts.EnergyLimit) } 102 103 // GetSigner cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) 104 // func (opts *TransactOpts) GetSigner() Signer { return &signer{opts.opts.Signer} } 105 106 // GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876) 107 // Even then it's awkward to unpack the subtleties of a Go context out to Java. 108 //func (opts *TransactOpts) GetContext() *Context { return &Context{opts.opts.Context} } 109 110 func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address } 111 func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) } 112 func (opts *TransactOpts) SetSigner(s Signer) { 113 opts.opts.Signer = func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 114 sig, err := s.Sign(&Address{addr}, &Transaction{tx}) 115 if err != nil { 116 return nil, err 117 } 118 return sig.tx, nil 119 } 120 } 121 func (opts *TransactOpts) SetValue(value *BigInt) { opts.opts.Value = value.bigint } 122 func (opts *TransactOpts) SetEnergyPrice(price *BigInt) { opts.opts.EnergyPrice = price.bigint } 123 func (opts *TransactOpts) SetEnergyLimit(limit int64) { opts.opts.EnergyLimit = uint64(limit) } 124 func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context } 125 126 // BoundContract is the base wrapper object that reflects a contract on the 127 // Core network. It contains a collection of methods that are used by the 128 // higher level contract bindings to operate. 129 type BoundContract struct { 130 contract *bind.BoundContract 131 address common.Address 132 deployer *types.Transaction 133 } 134 135 // DeployContract deploys a contract onto the Core blockchain and binds the 136 // deployment address with a wrapper. 137 func DeployContract(opts *TransactOpts, abiJSON string, bytecode []byte, client *CoreClient, args *Interfaces) (contract *BoundContract, _ error) { 138 // Deploy the contract to the network 139 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 140 if err != nil { 141 return nil, err 142 } 143 addr, tx, bound, err := bind.DeployContract(&opts.opts, parsed, common.CopyBytes(bytecode), client.client, args.objects...) 144 if err != nil { 145 return nil, err 146 } 147 return &BoundContract{ 148 contract: bound, 149 address: addr, 150 deployer: tx, 151 }, nil 152 } 153 154 // BindContract creates a low level contract interface through which calls and 155 // transactions may be made through. 156 func BindContract(address *Address, abiJSON string, client *CoreClient) (contract *BoundContract, _ error) { 157 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 158 if err != nil { 159 return nil, err 160 } 161 return &BoundContract{ 162 contract: bind.NewBoundContract(address.address, parsed, client.client, client.client, client.client), 163 address: address.address, 164 }, nil 165 } 166 167 func (c *BoundContract) GetAddress() *Address { return &Address{c.address} } 168 func (c *BoundContract) GetDeployer() *Transaction { 169 if c.deployer == nil { 170 return nil 171 } 172 return &Transaction{c.deployer} 173 } 174 175 // Call invokes the (constant) contract method with params as input values and 176 // sets the output to result. 177 func (c *BoundContract) Call(opts *CallOpts, out *Interfaces, method string, args *Interfaces) error { 178 results := make([]interface{}, len(out.objects)) 179 copy(results, out.objects) 180 if err := c.contract.Call(&opts.opts, &results, method, args.objects...); err != nil { 181 return err 182 } 183 copy(out.objects, results) 184 return nil 185 } 186 187 // Transact invokes the (paid) contract method with params as input values. 188 func (c *BoundContract) Transact(opts *TransactOpts, method string, args *Interfaces) (tx *Transaction, _ error) { 189 rawTx, err := c.contract.Transact(&opts.opts, method, args.objects...) 190 if err != nil { 191 return nil, err 192 } 193 return &Transaction{rawTx}, nil 194 } 195 196 // RawTransact invokes the (paid) contract method with raw calldata as input values. 197 func (c *BoundContract) RawTransact(opts *TransactOpts, calldata []byte) (tx *Transaction, _ error) { 198 rawTx, err := c.contract.RawTransact(&opts.opts, calldata) 199 if err != nil { 200 return nil, err 201 } 202 return &Transaction{rawTx}, nil 203 } 204 205 // Transfer initiates a plain transaction to move funds to the contract, calling 206 // its default method if one is available. 207 func (c *BoundContract) Transfer(opts *TransactOpts) (tx *Transaction, _ error) { 208 rawTx, err := c.contract.Transfer(&opts.opts) 209 if err != nil { 210 return nil, err 211 } 212 return &Transaction{rawTx}, nil 213 }