OSDN Git Service

add the argument type "Sign" to support checking signature for message (#27)
authoroysheng <33340252+oysheng@users.noreply.github.com>
Mon, 26 Nov 2018 07:57:38 +0000 (15:57 +0800)
committerPaladz <yzhu101@uottawa.ca>
Mon, 26 Nov 2018 07:57:38 +0000 (15:57 +0800)
add buildin function checkMsgSig

compiler/builtins.go
compiler/checks.go
compiler/cmd/equitycmd/equitycmd.go
compiler/compile.go
compiler/compile_test.go
compiler/types.go
equity/util/instance.go

index f7e3a3e..1bd36bb 100644 (file)
@@ -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},
index de14e06..a10fa92 100644 (file)
@@ -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)
                }
index 4524615..a567fa2 100644 (file)
@@ -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
index 4b181b5..4cb0fc5 100644 (file)
@@ -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)
                        }
index e11e641..4c84953 100644 (file)
@@ -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 {
index 1252de3..1033237 100644 (file)
@@ -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,
index e065fdd..b96c5cc 100644 (file)
@@ -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 {