72 lines
2 KiB
Go
72 lines
2 KiB
Go
|
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
|
||
|
}
|