neoneo-go/pkg/core/interop/contract/account.go

72 lines
2 KiB
Go
Raw Permalink Normal View History

package contract
import (
"crypto/elliptic"
"errors"
"math"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/fee"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
// CreateMultisigAccount calculates multisig contract scripthash for a
// given m and a set of public keys.
func CreateMultisigAccount(ic *interop.Context) error {
m := ic.VM.Estack().Pop().BigInt()
mu64 := m.Uint64()
if !m.IsUint64() || mu64 > math.MaxInt32 {
return errors.New("m must be positive and fit int32")
}
arr := ic.VM.Estack().Pop().Array()
pubs := make(keys.PublicKeys, len(arr))
for i, pk := range arr {
p, err := keys.NewPublicKeyFromBytes(pk.Value().([]byte), elliptic.P256())
if err != nil {
return err
}
pubs[i] = p
}
var invokeFee int64
if ic.IsHardforkEnabled(config.HFAspidochelone) {
invokeFee = fee.ECDSAVerifyPrice * int64(len(pubs))
} else {
invokeFee = 1 << 8
}
invokeFee *= ic.BaseExecFee()
if !ic.VM.AddGas(invokeFee) {
return errors.New("gas limit exceeded")
}
script, err := smartcontract.CreateMultiSigRedeemScript(int(mu64), pubs)
if err != nil {
return err
}
ic.VM.Estack().PushItem(stackitem.NewByteArray(hash.Hash160(script).BytesBE()))
return nil
}
// CreateStandardAccount calculates contract scripthash for a given public key.
func CreateStandardAccount(ic *interop.Context) error {
h := ic.VM.Estack().Pop().Bytes()
p, err := keys.NewPublicKeyFromBytes(h, elliptic.P256())
if err != nil {
return err
}
var invokeFee int64
if ic.IsHardforkEnabled(config.HFAspidochelone) {
invokeFee = fee.ECDSAVerifyPrice
} else {
invokeFee = 1 << 8
}
invokeFee *= ic.BaseExecFee()
if !ic.VM.AddGas(invokeFee) {
return errors.New("gas limit exceeded")
}
ic.VM.Estack().PushItem(stackitem.NewByteArray(p.GetScriptHash().BytesBE()))
return nil
}