forked from TrueCloudLab/neoneo-go
dba248236c
And use it where appropriate. Some of our code was just plain wrong (like the one in GAS contract) and unification is always useful here.
45 lines
1.4 KiB
Go
45 lines
1.4 KiB
Go
package smartcontract
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
|
)
|
|
|
|
// CreateMultiSigRedeemScript creates an "m out of n" type verification script
|
|
// where n is the length of publicKeys.
|
|
func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, error) {
|
|
if m < 1 {
|
|
return nil, fmt.Errorf("param m cannot be smaller or equal to 1 got %d", m)
|
|
}
|
|
if m > len(publicKeys) {
|
|
return nil, fmt.Errorf("length of the signatures (%d) is higher then the number of public keys", m)
|
|
}
|
|
if m > 1024 {
|
|
return nil, fmt.Errorf("public key count %d exceeds maximum of length 1024", len(publicKeys))
|
|
}
|
|
|
|
buf := io.NewBufBinWriter()
|
|
emit.Int(buf.BinWriter, int64(m))
|
|
sort.Sort(publicKeys)
|
|
for _, pubKey := range publicKeys {
|
|
emit.Bytes(buf.BinWriter, pubKey.Bytes())
|
|
}
|
|
emit.Int(buf.BinWriter, int64(len(publicKeys)))
|
|
emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
|
|
emit.Syscall(buf.BinWriter, "Neo.Crypto.CheckMultisigWithECDsaSecp256r1")
|
|
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
// CreateDefaultMultiSigRedeemScript creates an "m out of n" type verification script
|
|
// using publicKeys length with the default BFT assumptions of (n - (n-1)/3) for m.
|
|
func CreateDefaultMultiSigRedeemScript(publicKeys keys.PublicKeys) ([]byte, error) {
|
|
n := len(publicKeys)
|
|
m := n - (n-1)/3
|
|
return CreateMultiSigRedeemScript(m, publicKeys)
|
|
}
|