From: oysheng <33340252+oysheng@users.noreply.github.com> Date: Mon, 26 Nov 2018 07:57:38 +0000 (+0800) Subject: add the argument type "Sign" to support checking signature for message (#27) X-Git-Tag: v0.1.1~7 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=8b24b60ff0e5cd5ee490067023113fd4ff847e1e;p=bytom%2Fequity.git add the argument type "Sign" to support checking signature for message (#27) add buildin function checkMsgSig --- diff --git a/compiler/builtins.go b/compiler/builtins.go index f7e3a3e..1bd36bb 100644 --- a/compiler/builtins.go +++ b/compiler/builtins.go @@ -15,6 +15,7 @@ var builtins = []builtin{ {"min", "MIN", []typeDesc{intType, intType}, intType}, {"max", "MAX", []typeDesc{intType, intType}, intType}, {"checkTxSig", "TXSIGHASH SWAP CHECKSIG", []typeDesc{pubkeyType, sigType}, boolType}, + {"checkMsgSig", "CHECKSIG", []typeDesc{pubkeyType, hashType, signType}, boolType}, {"concat", "CAT", []typeDesc{nilType, nilType}, strType}, {"concatpush", "CATPUSHDATA", []typeDesc{nilType, nilType}, strType}, {"below", "BLOCKHEIGHT GREATERTHAN", []typeDesc{intType}, boolType}, diff --git a/compiler/checks.go b/compiler/checks.go index de14e06..a10fa92 100644 --- a/compiler/checks.go +++ b/compiler/checks.go @@ -247,13 +247,13 @@ func typeCheckStatement(stat statement, contractValue ValueInfo, clauseName stri } case *defineStatement: - if stmt.expr != nil && stmt.expr.typ(env) != stmt.variable.Type && !isHashSubtype(stmt.expr.typ(env)) { + if stmt.expr != nil && stmt.expr.typ(env) != stmt.variable.Type && !(stmt.variable.Type == hashType && isHashSubtype(stmt.expr.typ(env))) { return fmt.Errorf("expression in define statement in clause \"%s\" has type \"%s\", must be \"%s\"", clauseName, stmt.expr.typ(env), stmt.variable.Type) } case *assignStatement: - if stmt.expr.typ(env) != stmt.variable.Type && !isHashSubtype(stmt.expr.typ(env)) { + if stmt.expr.typ(env) != stmt.variable.Type && !(stmt.variable.Type == hashType && isHashSubtype(stmt.expr.typ(env))) { return fmt.Errorf("expression in assign statement in clause \"%s\" has type \"%s\", must be \"%s\"", clauseName, stmt.expr.typ(env), stmt.variable.Type) } diff --git a/compiler/cmd/equitycmd/equitycmd.go b/compiler/cmd/equitycmd/equitycmd.go index 4524615..a567fa2 100644 --- a/compiler/cmd/equitycmd/equitycmd.go +++ b/compiler/cmd/equitycmd/equitycmd.go @@ -128,7 +128,7 @@ func main() { fmt.Fprintf(buf, "\t_contractArgs = append(_contractArgs, compiler.ContractArg{B: &%s})\n", param.Name) case "Integer": fmt.Fprintf(buf, "\t_contractArgs = append(_contractArgs, compiler.ContractArg{I: &%s})\n", param.Name) - case "Hash", "Program", "PublicKey", "Signature", "String": + case "Hash", "Program", "PublicKey", "Signature", "Sign", "String": fmt.Fprintf(buf, "\t_contractArgs = append(_contractArgs, compiler.ContractArg{S: (*json.HexBytes)(&%s)})\n", param.Name) } } @@ -273,6 +273,9 @@ func asGoParams(params []*compiler.Param) (goParams string, imports []string) { case "Signature": typ = "[]byte" strFlag = true + case "Sign": + typ = "[]byte" + strFlag = true case "String": typ = "[]byte" strFlag = true diff --git a/compiler/compile.go b/compiler/compile.go index 4b181b5..4cb0fc5 100644 --- a/compiler/compile.go +++ b/compiler/compile.go @@ -122,7 +122,7 @@ func Instantiate(body []byte, params []*Param, recursive bool, args []ContractAr if arg.I == nil { return nil, fmt.Errorf("type mismatch in arg %d (want integer)", i) } - case assetType, hashType, progType, pubkeyType, sigType, strType: + case assetType, hashType, progType, pubkeyType, sigType, signType, strType: if arg.S == nil { return nil, fmt.Errorf("type mismatch in arg %d (want string)", i) } diff --git a/compiler/compile_test.go b/compiler/compile_test.go index e11e641..4c84953 100644 --- a/compiler/compile_test.go +++ b/compiler/compile_test.go @@ -227,6 +227,16 @@ contract TestConstantMath(result: Integer, hashByte: Hash, hashStr: Hash, outcom } ` +const VerifySignature = ` +contract VerifySignature(sig1: Sign, sig2: Sign, msgHash: Hash) locks valueAmount of valueAsset { + clause check(publicKey1: PublicKey, publicKey2: PublicKey) { + verify checkMsgSig(publicKey1, msgHash, sig1) + verify checkMsgSig(publicKey2, msgHash, sig2) + unlock valueAmount of valueAsset + } +} +` + func TestCompile(t *testing.T) { cases := []struct { name string @@ -318,6 +328,11 @@ func TestCompile(t *testing.T) { TestConstantMath, "765779577a935a93887c0431323330aa887c06737472696e67aa887c91697b011493879a", }, + { + "VerifySignature", + VerifySignature, + "5279557aac697c7bac", + }, } for _, c := range cases { diff --git a/compiler/types.go b/compiler/types.go index 1252de3..1033237 100644 --- a/compiler/types.go +++ b/compiler/types.go @@ -15,6 +15,7 @@ var ( progType = typeDesc("Program") pubkeyType = typeDesc("PublicKey") sigType = typeDesc("Signature") + signType = typeDesc("Sign") strType = typeDesc("String") sha3StrType = typeDesc("Sha3(String)") @@ -35,6 +36,7 @@ var types = map[string]typeDesc{ string(progType): progType, string(pubkeyType): pubkeyType, string(sigType): sigType, + string(signType): signType, string(strType): strType, string(sha3StrType): sha3StrType, diff --git a/equity/util/instance.go b/equity/util/instance.go index e065fdd..b96c5cc 100644 --- a/equity/util/instance.go +++ b/equity/util/instance.go @@ -20,6 +20,7 @@ func InstantiateContract(contract *compiler.Contract, args []compiler.ContractAr return program, nil } +// ConvertArguments convert input argument into contract argument func ConvertArguments(contract *compiler.Contract, args []string) ([]compiler.ContractArg, error) { var contractArgs []compiler.ContractArg for i, p := range contract.Params { @@ -66,6 +67,17 @@ func ConvertArguments(contract *compiler.Contract, args []string) ([]compiler.Co } argument.S = (*chainjson.HexBytes)(&commonValue) + case "Sign": + if len(args[i]) != 128 { + return nil, errors.New("mismatch length for Sign argument") + } + + signValue, err := hex.DecodeString(args[i]) + if err != nil { + return nil, err + } + argument.S = (*chainjson.HexBytes)(&signValue) + case "Program": program, err := hex.DecodeString(args[i]) if err != nil {