修訂 | 8b24b60ff0e5cd5ee490067023113fd4ff847e1e (tree) |
---|---|
時間 | 2018-11-26 16:57:38 |
作者 | oysheng <33340252+oysheng@user...> |
Commiter | Paladz |
add the argument type "Sign" to support checking signature for message (#27)
add buildin function checkMsgSig
@@ -15,6 +15,7 @@ var builtins = []builtin{ | ||
15 | 15 | {"min", "MIN", []typeDesc{intType, intType}, intType}, |
16 | 16 | {"max", "MAX", []typeDesc{intType, intType}, intType}, |
17 | 17 | {"checkTxSig", "TXSIGHASH SWAP CHECKSIG", []typeDesc{pubkeyType, sigType}, boolType}, |
18 | + {"checkMsgSig", "CHECKSIG", []typeDesc{pubkeyType, hashType, signType}, boolType}, | |
18 | 19 | {"concat", "CAT", []typeDesc{nilType, nilType}, strType}, |
19 | 20 | {"concatpush", "CATPUSHDATA", []typeDesc{nilType, nilType}, strType}, |
20 | 21 | {"below", "BLOCKHEIGHT GREATERTHAN", []typeDesc{intType}, boolType}, |
@@ -247,13 +247,13 @@ func typeCheckStatement(stat statement, contractValue ValueInfo, clauseName stri | ||
247 | 247 | } |
248 | 248 | |
249 | 249 | case *defineStatement: |
250 | - if stmt.expr != nil && stmt.expr.typ(env) != stmt.variable.Type && !isHashSubtype(stmt.expr.typ(env)) { | |
250 | + if stmt.expr != nil && stmt.expr.typ(env) != stmt.variable.Type && !(stmt.variable.Type == hashType && isHashSubtype(stmt.expr.typ(env))) { | |
251 | 251 | return fmt.Errorf("expression in define statement in clause \"%s\" has type \"%s\", must be \"%s\"", |
252 | 252 | clauseName, stmt.expr.typ(env), stmt.variable.Type) |
253 | 253 | } |
254 | 254 | |
255 | 255 | case *assignStatement: |
256 | - if stmt.expr.typ(env) != stmt.variable.Type && !isHashSubtype(stmt.expr.typ(env)) { | |
256 | + if stmt.expr.typ(env) != stmt.variable.Type && !(stmt.variable.Type == hashType && isHashSubtype(stmt.expr.typ(env))) { | |
257 | 257 | return fmt.Errorf("expression in assign statement in clause \"%s\" has type \"%s\", must be \"%s\"", |
258 | 258 | clauseName, stmt.expr.typ(env), stmt.variable.Type) |
259 | 259 | } |
@@ -128,7 +128,7 @@ func main() { | ||
128 | 128 | fmt.Fprintf(buf, "\t_contractArgs = append(_contractArgs, compiler.ContractArg{B: &%s})\n", param.Name) |
129 | 129 | case "Integer": |
130 | 130 | fmt.Fprintf(buf, "\t_contractArgs = append(_contractArgs, compiler.ContractArg{I: &%s})\n", param.Name) |
131 | - case "Hash", "Program", "PublicKey", "Signature", "String": | |
131 | + case "Hash", "Program", "PublicKey", "Signature", "Sign", "String": | |
132 | 132 | fmt.Fprintf(buf, "\t_contractArgs = append(_contractArgs, compiler.ContractArg{S: (*json.HexBytes)(&%s)})\n", param.Name) |
133 | 133 | } |
134 | 134 | } |
@@ -273,6 +273,9 @@ func asGoParams(params []*compiler.Param) (goParams string, imports []string) { | ||
273 | 273 | case "Signature": |
274 | 274 | typ = "[]byte" |
275 | 275 | strFlag = true |
276 | + case "Sign": | |
277 | + typ = "[]byte" | |
278 | + strFlag = true | |
276 | 279 | case "String": |
277 | 280 | typ = "[]byte" |
278 | 281 | strFlag = true |
@@ -122,7 +122,7 @@ func Instantiate(body []byte, params []*Param, recursive bool, args []ContractAr | ||
122 | 122 | if arg.I == nil { |
123 | 123 | return nil, fmt.Errorf("type mismatch in arg %d (want integer)", i) |
124 | 124 | } |
125 | - case assetType, hashType, progType, pubkeyType, sigType, strType: | |
125 | + case assetType, hashType, progType, pubkeyType, sigType, signType, strType: | |
126 | 126 | if arg.S == nil { |
127 | 127 | return nil, fmt.Errorf("type mismatch in arg %d (want string)", i) |
128 | 128 | } |
@@ -227,6 +227,16 @@ contract TestConstantMath(result: Integer, hashByte: Hash, hashStr: Hash, outcom | ||
227 | 227 | } |
228 | 228 | ` |
229 | 229 | |
230 | +const VerifySignature = ` | |
231 | +contract VerifySignature(sig1: Sign, sig2: Sign, msgHash: Hash) locks valueAmount of valueAsset { | |
232 | + clause check(publicKey1: PublicKey, publicKey2: PublicKey) { | |
233 | + verify checkMsgSig(publicKey1, msgHash, sig1) | |
234 | + verify checkMsgSig(publicKey2, msgHash, sig2) | |
235 | + unlock valueAmount of valueAsset | |
236 | + } | |
237 | +} | |
238 | +` | |
239 | + | |
230 | 240 | func TestCompile(t *testing.T) { |
231 | 241 | cases := []struct { |
232 | 242 | name string |
@@ -318,6 +328,11 @@ func TestCompile(t *testing.T) { | ||
318 | 328 | TestConstantMath, |
319 | 329 | "765779577a935a93887c0431323330aa887c06737472696e67aa887c91697b011493879a", |
320 | 330 | }, |
331 | + { | |
332 | + "VerifySignature", | |
333 | + VerifySignature, | |
334 | + "5279557aac697c7bac", | |
335 | + }, | |
321 | 336 | } |
322 | 337 | |
323 | 338 | for _, c := range cases { |
@@ -15,6 +15,7 @@ var ( | ||
15 | 15 | progType = typeDesc("Program") |
16 | 16 | pubkeyType = typeDesc("PublicKey") |
17 | 17 | sigType = typeDesc("Signature") |
18 | + signType = typeDesc("Sign") | |
18 | 19 | strType = typeDesc("String") |
19 | 20 | |
20 | 21 | sha3StrType = typeDesc("Sha3(String)") |
@@ -35,6 +36,7 @@ var types = map[string]typeDesc{ | ||
35 | 36 | string(progType): progType, |
36 | 37 | string(pubkeyType): pubkeyType, |
37 | 38 | string(sigType): sigType, |
39 | + string(signType): signType, | |
38 | 40 | string(strType): strType, |
39 | 41 | |
40 | 42 | string(sha3StrType): sha3StrType, |
@@ -20,6 +20,7 @@ func InstantiateContract(contract *compiler.Contract, args []compiler.ContractAr | ||
20 | 20 | return program, nil |
21 | 21 | } |
22 | 22 | |
23 | +// ConvertArguments convert input argument into contract argument | |
23 | 24 | func ConvertArguments(contract *compiler.Contract, args []string) ([]compiler.ContractArg, error) { |
24 | 25 | var contractArgs []compiler.ContractArg |
25 | 26 | for i, p := range contract.Params { |
@@ -66,6 +67,17 @@ func ConvertArguments(contract *compiler.Contract, args []string) ([]compiler.Co | ||
66 | 67 | } |
67 | 68 | argument.S = (*chainjson.HexBytes)(&commonValue) |
68 | 69 | |
70 | + case "Sign": | |
71 | + if len(args[i]) != 128 { | |
72 | + return nil, errors.New("mismatch length for Sign argument") | |
73 | + } | |
74 | + | |
75 | + signValue, err := hex.DecodeString(args[i]) | |
76 | + if err != nil { | |
77 | + return nil, err | |
78 | + } | |
79 | + argument.S = (*chainjson.HexBytes)(&signValue) | |
80 | + | |
69 | 81 | case "Program": |
70 | 82 | program, err := hex.DecodeString(args[i]) |
71 | 83 | if err != nil { |