github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/interop/contract/account.go (about)

     1  package contract
     2  
     3  import (
     4  	"crypto/elliptic"
     5  	"errors"
     6  	"math"
     7  
     8  	"github.com/nspcc-dev/neo-go/pkg/config"
     9  	"github.com/nspcc-dev/neo-go/pkg/core/fee"
    10  	"github.com/nspcc-dev/neo-go/pkg/core/interop"
    11  	"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
    12  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
    13  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
    14  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
    15  )
    16  
    17  // CreateMultisigAccount calculates multisig contract scripthash for a
    18  // given m and a set of public keys.
    19  func CreateMultisigAccount(ic *interop.Context) error {
    20  	m := ic.VM.Estack().Pop().BigInt()
    21  	mu64 := m.Uint64()
    22  	if !m.IsUint64() || mu64 > math.MaxInt32 {
    23  		return errors.New("m must be positive and fit int32")
    24  	}
    25  	arr := ic.VM.Estack().Pop().Array()
    26  	pubs := make(keys.PublicKeys, len(arr))
    27  	for i, pk := range arr {
    28  		p, err := keys.NewPublicKeyFromBytes(pk.Value().([]byte), elliptic.P256())
    29  		if err != nil {
    30  			return err
    31  		}
    32  		pubs[i] = p
    33  	}
    34  	var invokeFee int64
    35  	if ic.IsHardforkEnabled(config.HFAspidochelone) {
    36  		invokeFee = fee.ECDSAVerifyPrice * int64(len(pubs))
    37  	} else {
    38  		invokeFee = 1 << 8
    39  	}
    40  	invokeFee *= ic.BaseExecFee()
    41  	if !ic.VM.AddGas(invokeFee) {
    42  		return errors.New("gas limit exceeded")
    43  	}
    44  	script, err := smartcontract.CreateMultiSigRedeemScript(int(mu64), pubs)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	ic.VM.Estack().PushItem(stackitem.NewByteArray(hash.Hash160(script).BytesBE()))
    49  	return nil
    50  }
    51  
    52  // CreateStandardAccount calculates contract scripthash for a given public key.
    53  func CreateStandardAccount(ic *interop.Context) error {
    54  	h := ic.VM.Estack().Pop().Bytes()
    55  	p, err := keys.NewPublicKeyFromBytes(h, elliptic.P256())
    56  	if err != nil {
    57  		return err
    58  	}
    59  	var invokeFee int64
    60  	if ic.IsHardforkEnabled(config.HFAspidochelone) {
    61  		invokeFee = fee.ECDSAVerifyPrice
    62  	} else {
    63  		invokeFee = 1 << 8
    64  	}
    65  	invokeFee *= ic.BaseExecFee()
    66  	if !ic.VM.AddGas(invokeFee) {
    67  		return errors.New("gas limit exceeded")
    68  	}
    69  	ic.VM.Estack().PushItem(stackitem.NewByteArray(p.GetScriptHash().BytesBE()))
    70  	return nil
    71  }