mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-05-03 11:41:48 +00:00
core: move transaction's sender to cosigners
Closes #1184 Ported changes from https://github.com/neo-project/neo/pull/1752
This commit is contained in:
parent
8697582b23
commit
90825efa16
36 changed files with 307 additions and 264 deletions
|
@ -345,31 +345,31 @@ func (c *Client) GetVersion() (*result.Version, error) {
|
|||
|
||||
// InvokeScript returns the result of the given script after running it true the VM.
|
||||
// NOTE: This is a test invoke and will not affect the blockchain.
|
||||
func (c *Client) InvokeScript(script []byte, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
||||
func (c *Client) InvokeScript(script []byte, signers []transaction.Signer) (*result.Invoke, error) {
|
||||
var p = request.NewRawParams(hex.EncodeToString(script))
|
||||
return c.invokeSomething("invokescript", p, cosigners)
|
||||
return c.invokeSomething("invokescript", p, signers)
|
||||
}
|
||||
|
||||
// InvokeFunction returns the results after calling the smart contract scripthash
|
||||
// with the given operation and parameters.
|
||||
// NOTE: this is test invoke and will not affect the blockchain.
|
||||
func (c *Client) InvokeFunction(contract util.Uint160, operation string, params []smartcontract.Parameter, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
||||
func (c *Client) InvokeFunction(contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) {
|
||||
var p = request.NewRawParams(contract.StringLE(), operation, params)
|
||||
return c.invokeSomething("invokefunction", p, cosigners)
|
||||
return c.invokeSomething("invokefunction", p, signers)
|
||||
}
|
||||
|
||||
// invokeSomething is an inner wrapper for Invoke* functions
|
||||
func (c *Client) invokeSomething(method string, p request.RawParams, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
||||
func (c *Client) invokeSomething(method string, p request.RawParams, signers []transaction.Signer) (*result.Invoke, error) {
|
||||
var resp = new(result.Invoke)
|
||||
if cosigners != nil {
|
||||
p.Values = append(p.Values, cosigners)
|
||||
if signers != nil {
|
||||
p.Values = append(p.Values, signers)
|
||||
}
|
||||
if err := c.performRequest(method, p, resp); err != nil {
|
||||
// Retry with old-fashioned hashes (see neo/neo-modules#260).
|
||||
if cosigners != nil {
|
||||
var hashes = make([]util.Uint160, len(cosigners))
|
||||
for i := range cosigners {
|
||||
hashes[i] = cosigners[i].Account
|
||||
if signers != nil {
|
||||
var hashes = make([]util.Uint160, len(signers))
|
||||
for i := range signers {
|
||||
hashes[i] = signers[i].Account
|
||||
}
|
||||
p.Values[len(p.Values)-1] = hashes
|
||||
err = c.performRequest(method, p, resp)
|
||||
|
@ -419,13 +419,18 @@ func (c *Client) SubmitBlock(b block.Block) (util.Uint256, error) {
|
|||
// SignAndPushInvocationTx signs and pushes given script as an invocation
|
||||
// transaction using given wif to sign it and spending the amount of gas
|
||||
// specified. It returns a hash of the invocation transaction and an error.
|
||||
func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sysfee int64, netfee util.Fixed8, cosigners []transaction.Cosigner) (util.Uint256, error) {
|
||||
func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sysfee int64, netfee util.Fixed8, cosigners []transaction.Signer) (util.Uint256, error) {
|
||||
var txHash util.Uint256
|
||||
var err error
|
||||
|
||||
tx := transaction.New(c.opts.Network, script, sysfee)
|
||||
tx.SystemFee = sysfee
|
||||
tx.Cosigners = cosigners
|
||||
|
||||
addr, err := address.StringToUint160(acc.Address)
|
||||
if err != nil {
|
||||
return txHash, errors.Wrap(err, "failed to get address")
|
||||
}
|
||||
tx.Signers = getSigners(addr, cosigners)
|
||||
|
||||
validUntilBlock, err := c.CalculateValidUntilBlock()
|
||||
if err != nil {
|
||||
|
@ -433,12 +438,6 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys
|
|||
}
|
||||
tx.ValidUntilBlock = validUntilBlock
|
||||
|
||||
addr, err := address.StringToUint160(acc.Address)
|
||||
if err != nil {
|
||||
return txHash, errors.Wrap(err, "failed to get address")
|
||||
}
|
||||
tx.Sender = addr
|
||||
|
||||
err = c.AddNetworkFee(tx, int64(netfee), acc)
|
||||
if err != nil {
|
||||
return txHash, errors.Wrapf(err, "failed to add network fee")
|
||||
|
@ -458,6 +457,27 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys
|
|||
return txHash, nil
|
||||
}
|
||||
|
||||
// getSigners returns an array of transaction signers from given sender and cosigners.
|
||||
// If cosigners list already contains sender, the sender will be placed at the start of
|
||||
// the list.
|
||||
func getSigners(sender util.Uint160, cosigners []transaction.Signer) []transaction.Signer {
|
||||
s := transaction.Signer{
|
||||
Account: sender,
|
||||
Scopes: transaction.FeeOnly,
|
||||
}
|
||||
for i, c := range cosigners {
|
||||
if c.Account == sender {
|
||||
if i == 0 {
|
||||
return cosigners
|
||||
}
|
||||
s.Scopes = c.Scopes
|
||||
cosigners = append(cosigners[:i], cosigners[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return append([]transaction.Signer{s}, cosigners...)
|
||||
}
|
||||
|
||||
// ValidateAddress verifies that the address is a correct NEO address.
|
||||
func (c *Client) ValidateAddress(address string) error {
|
||||
var (
|
||||
|
@ -513,7 +533,7 @@ func (c *Client) AddNetworkFee(tx *transaction.Transaction, extraFee int64, acc
|
|||
tx.NetworkFee += netFee
|
||||
size += sizeDelta
|
||||
}
|
||||
for _, cosigner := range tx.Cosigners {
|
||||
for _, cosigner := range tx.Signers {
|
||||
script := acc.Contract.Script
|
||||
if !cosigner.Account.Equals(hash.Hash160(acc.Contract.Script)) {
|
||||
contract, err := c.GetContractState(cosigner.Account)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue