{"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},
}
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)
}
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)
}
}
case "Signature":
typ = "[]byte"
strFlag = true
+ case "Sign":
+ typ = "[]byte"
+ strFlag = true
case "String":
typ = "[]byte"
strFlag = true
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)
}
}
`
+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
TestConstantMath,
"765779577a935a93887c0431323330aa887c06737472696e67aa887c91697b011493879a",
},
+ {
+ "VerifySignature",
+ VerifySignature,
+ "5279557aac697c7bac",
+ },
}
for _, c := range cases {
progType = typeDesc("Program")
pubkeyType = typeDesc("PublicKey")
sigType = typeDesc("Signature")
+ signType = typeDesc("Sign")
strType = typeDesc("String")
sha3StrType = typeDesc("Sha3(String)")
string(progType): progType,
string(pubkeyType): pubkeyType,
string(sigType): sigType,
+ string(signType): signType,
string(strType): strType,
string(sha3StrType): sha3StrType,
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 {
}
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 {