Skip to content

Commit

Permalink
add verifySig and verifyMutiSig Api support (#829)
Browse files Browse the repository at this point in the history
* add verifySig and verifyMutiSig Api support

* Update verify muti signs

* fix return error

* fix error pop

* add verifysig_test.go and update multi sig (DNAProject#6)

* remove unused code

* remove unused code

* update verify muti sig to API

* fix error name

* Verify sig (DNAProject#8)

* update verifysig_test.go

* update verifysig_test.go 2nd
  • Loading branch information
tanZiWen authored and laizy committed Jun 20, 2019
1 parent fe819b3 commit 546864f
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 1 deletion.
4 changes: 4 additions & 0 deletions smartcontract/service/neovm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var (
STORAGE_PUT_GAS uint64 = 4000
STORAGE_DELETE_GAS uint64 = 100
RUNTIME_CHECKWITNESS_GAS uint64 = 200
RUNTIME_VERIFYMUTISIG_GAS uint64 = 400
RUNTIME_ADDRESSTOBASE58_GAS uint64 = 40
RUNTIME_BASE58TOADDRESS_GAS uint64 = 30
APPCALL_GAS uint64 = 10
Expand Down Expand Up @@ -102,6 +103,7 @@ var (
RUNTIME_BASE58TOADDRESS_NAME = "Ontology.Runtime.Base58ToAddress"
RUNTIME_ADDRESSTOBASE58_NAME = "Ontology.Runtime.AddressToBase58"
RUNTIME_GETCURRENTBLOCKHASH_NAME = "Ontology.Runtime.GetCurrentBlockHash"
RUNTIME_VERIFYMUTISIG_NAME = "Ontology.Runtime.VerifyMutiSig"

NATIVE_INVOKE_NAME = "Ontology.Native.Invoke"

Expand Down Expand Up @@ -191,5 +193,7 @@ func initGAS_TABLE() *sync.Map {
m.Store(RUNTIME_BASE58TOADDRESS_NAME, RUNTIME_BASE58TOADDRESS_GAS)
m.Store(RUNTIME_ADDRESSTOBASE58_NAME, RUNTIME_ADDRESSTOBASE58_GAS)

m.Store(RUNTIME_VERIFYMUTISIG_NAME, RUNTIME_VERIFYMUTISIG_GAS)

return &m
}
1 change: 1 addition & 0 deletions smartcontract/service/neovm/neovm_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ var (
RUNTIME_GETTRIGGER_NAME: {Execute: RuntimeGetTrigger},
RUNTIME_SERIALIZE_NAME: {Execute: RuntimeSerialize, Validator: validatorSerialize},
RUNTIME_DESERIALIZE_NAME: {Execute: RuntimeDeserialize, Validator: validatorDeserialize},
RUNTIME_VERIFYMUTISIG_NAME: {Execute: RuntimeVerifyMutiSig},
NATIVE_INVOKE_NAME: {Execute: NativeInvoke},
STORAGE_GET_NAME: {Execute: StorageGet},
STORAGE_PUT_NAME: {Execute: StoragePut},
Expand Down
50 changes: 50 additions & 0 deletions smartcontract/service/neovm/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/ontio/ontology-crypto/keypair"
"github.com/ontio/ontology/common"
"github.com/ontio/ontology/common/serialization"
"github.com/ontio/ontology/core/signature"
"github.com/ontio/ontology/core/types"
"github.com/ontio/ontology/errors"
scommon "github.com/ontio/ontology/smartcontract/common"
Expand Down Expand Up @@ -96,6 +97,55 @@ func RuntimeDeserialize(service *NeoVmService, engine *vm.ExecutionEngine) error
return nil
}

func RuntimeVerifyMutiSig(service *NeoVmService, engine *vm.ExecutionEngine) error {
if vm.EvaluationStackCount(engine) < 4 {
return errors.NewErr("[RuntimeVerifyMutiSig] Too few input parameters")
}
data, err := vm.PopByteArray(engine)
if err != nil {
return err
}
arr1, err := vm.PopArray(engine)
if err != nil {
return err
}
pks := make([]keypair.PublicKey, 0, len(arr1))
for i := 0; i < len(arr1); i++ {
value, err := arr1[i].GetByteArray()
if err != nil {
return err
}
pk, err := keypair.DeserializePublicKey(value)
if err != nil {
return err
}
pks = append(pks, pk)
}

m, err := vm.PopInt(engine)
if err != nil {
return err
}
arr2, err := vm.PopArray(engine)
if err != nil {
return err
}
signs := make([][]byte, 0, len(arr2))
for i := 0; i < len(arr2); i++ {
value, err := arr2[i].GetByteArray()
if err != nil {
return err
}
signs = append(signs, value)
}
if err := signature.VerifyMultiSignature(data, pks, m, signs); err != nil {
vm.PushData(engine, false)
} else {
vm.PushData(engine, true)
}
return nil
}

// RuntimeNotify put smart contract execute event notify to notifications
func RuntimeNotify(service *NeoVmService, engine *vm.ExecutionEngine) error {
item := vm.PopStackItem(engine)
Expand Down
111 changes: 111 additions & 0 deletions smartcontract/test/verifysig_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (C) 2018 The ontology Authors
* This file is part of The ontology library.
*
* The ontology is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ontology is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with The ontology. If not, see <http://www.gnu.org/licenses/>.
*/

package test

import (
"fmt"
"github.com/ontio/ontology-crypto/keypair"
"github.com/ontio/ontology/account"
"github.com/ontio/ontology/common"
"github.com/ontio/ontology/core/signature"
"github.com/ontio/ontology/smartcontract"
svm "github.com/ontio/ontology/smartcontract/service/neovm"
"github.com/ontio/ontology/vm/neovm"
vtypes "github.com/ontio/ontology/vm/neovm/types"
"testing"
)

func TestVerifySig(t *testing.T) {
/**
# the code of source python.
Cversion = '2.0.0'
from ontology.interop.Ontology.Runtime import VerifyMutiSig
def Main(data, pks_list, m, sig_list):
return VerifyMutiSig(data, pks_list, m, sig_list)
**/
code := `52c56b05322e302e306a00527ac46c59c56b6a00527ac46a51527ac46a52527ac46a53527ac46a54527ac46a54c36a53c36a52c36a51c3681e4f6e746f6c6f67792e52756e74696d652e5665726966794d7574695369676c75660111c56b6a00527ac46a51527ac46a51c300947600a0640c00c16a52527ac4620e007562030000c56a52527ac46a52c3c0517d9c7c75641c00006a53527ac46a52c300c36a54527ac4516a55527ac4625c006a52c3c0527d9c7c756421006a52c300c36a53527ac46a52c351c36a54527ac4516a55527ac4616232006a52c3c0537d9c7c756424006a52c300c36a53527ac46a52c351c36a54527ac46a52c352c36a55527ac462050000f100c176c96a56527ac46a53c36a57527ac46a57c36a54c37d9f7c756419006a56c36a57c3c86a57c36a55c3936a57527ac462e0ff6a56c36c7566`

data_pre := []byte{1, 2, 3}
data := neovm.NewStackItem(vtypes.NewByteArray(data_pre))
pks_list := make([]vtypes.StackItems, 0)
sigs_list := make([]vtypes.StackItems, 0)

accs := make([]*account.Account, 0)
N := 4
for i := 0; i < N; i++ {
accs = append(accs, account.NewAccount(""))
}

for _, acc := range accs {
sig, _ := signature.Sign(acc, data_pre)
key0 := neovm.NewStackItem(vtypes.NewByteArray(sig))
sigs_list = append(sigs_list, key0)

pk := keypair.SerializePublicKey(acc.PublicKey)
key1 := neovm.NewStackItem(vtypes.NewByteArray(pk))
pks_list = append(pks_list, key1)
}

hex, err := common.HexToBytes(code)

if err != nil {
t.Fatal("hex to byte error:", err)
}

config := &smartcontract.Config{
Time: 10,
Height: 10,
Tx: nil,
}
sc := smartcontract.SmartContract{
Config: config,
Gas: 100000,
}
engine, err := sc.NewExecuteEngine(hex)

if err != nil {
t.Fatal("hex to byte error:", err)
}

var service *svm.NeoVmService
service = engine.(*svm.NeoVmService)
e := service.Engine
neovm.PushData(e, sigs_list)
neovm.PushData(e, N)
neovm.PushData(e, pks_list)
neovm.PushData(e, data)

_, err = engine.Invoke()
if err != nil {
t.Fatal("multisignature inovke err:", err)
}

arr, err := neovm.PopBoolean(e)
if err != nil {
t.Fatal("multisignature PopBoolean err:", err)
}

if !arr {
t.Fatal("multisignature failed")
}

fmt.Printf("multisignature passed\n")

}
2 changes: 1 addition & 1 deletion vm/neovm/opcode_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ var (
HASH256: {Opcode: HASH256, Name: "HASH256", Exec: opHash, Validator: validateCount1},
VERIFY: {Opcode: VERIFY, Name: "VERIFY"},
//CHECKSIG: {Opcode: CHECKSIG, Name: "CHECKSIG", Exec: opCheckSig, Validator: validateCount2},
//CHECKMULTISIG: {Opcode: CHECKMULTISIG, Name: "CHECKMULTISIG", Exec: opCheckMultiSig, Validator: validateCount2},
//CHECKMULTISIG: {Opcode: CHECKMULTISIG, Name: "CHECKMULTISIG"},

//Array
ARRAYSIZE: {Opcode: ARRAYSIZE, Name: "ARRAYSIZE", Exec: opArraySize, Validator: validateCount1},
Expand Down

0 comments on commit 546864f

Please sign in to comment.