10 contract TrivialLock() locks amount of asset {
11 clause trivialUnlock() {
12 unlock amount of asset
17 const LockWithPublicKey = `
18 contract LockWithPublicKey(publicKey: PublicKey) locks amount of asset {
19 clause unlockWithSig(sig: Signature) {
20 verify checkTxSig(publicKey, sig)
21 unlock amount of asset
26 const LockWithPKHash = `
27 contract LockWithPublicKeyHash(pubKeyHash: Hash) locks amount of asset {
28 clause spend(pubKey: PublicKey, sig: Signature) {
29 verify sha3(pubKey) == pubKeyHash
30 verify checkTxSig(pubKey, sig)
31 unlock amount of asset
36 const LockWith2of3Keys = `
37 contract LockWith3Keys(pubkey1, pubkey2, pubkey3: PublicKey) locks amount of asset {
38 clause unlockWith2Sigs(sig1, sig2: Signature) {
39 verify checkTxMultiSig([pubkey1, pubkey2, pubkey3], [sig1, sig2])
40 unlock amount of asset
45 const LockToOutput = `
46 contract LockToOutput(address: Program) locks amount of asset {
48 lock amount of asset with address
54 contract TradeOffer(requestedAsset: Asset, requestedAmount: Amount, sellerProgram: Program, sellerKey: PublicKey) locks amount of asset {
56 lock requestedAmount of requestedAsset with sellerProgram
57 unlock amount of asset
59 clause cancel(sellerSig: Signature) {
60 verify checkTxSig(sellerKey, sellerSig)
61 unlock amount of asset
66 const EscrowedTransfer = `
67 contract EscrowedTransfer(agent: PublicKey, sender: Program, recipient: Program) locks amount of asset {
68 clause approve(sig: Signature) {
69 verify checkTxSig(agent, sig)
70 lock amount of asset with recipient
72 clause reject(sig: Signature) {
73 verify checkTxSig(agent, sig)
74 lock amount of asset with sender
79 const CollateralizedLoan = `
80 contract CollateralizedLoan(balanceAsset: Asset, balanceAmount: Amount, finalHeight: Integer, lender: Program, borrower: Program) locks valueAmount of valueAsset {
82 lock balanceAmount of balanceAsset with lender
83 lock valueAmount of valueAsset with borrower
86 verify above(finalHeight)
87 lock valueAmount of valueAsset with lender
92 const RevealPreimage = `
93 contract RevealPreimage(hash: Hash) locks amount of asset {
94 clause reveal(string: String) {
95 verify sha3(string) == hash
96 unlock amount of asset
101 const PriceChanger = `
102 contract PriceChanger(askAmount: Amount, askAsset: Asset, sellerKey: PublicKey, sellerProg: Program) locks valueAmount of valueAsset {
103 clause changePrice(newAmount: Amount, newAsset: Asset, sig: Signature) {
104 verify checkTxSig(sellerKey, sig)
105 lock valueAmount of valueAsset with PriceChanger(newAmount, newAsset, sellerKey, sellerProg)
108 lock askAmount of askAsset with sellerProg
109 unlock valueAmount of valueAsset
114 const CallOptionWithSettlement = `
115 contract CallOptionWithSettlement(strikePrice: Amount,
116 strikeCurrency: Asset,
117 sellerProgram: Program,
118 sellerKey: PublicKey,
120 finalHeight: Integer) locks valueAmount of valueAsset {
121 clause exercise(buyerSig: Signature) {
122 verify below(finalHeight)
123 verify checkTxSig(buyerKey, buyerSig)
124 lock strikePrice of strikeCurrency with sellerProgram
125 unlock valueAmount of valueAsset
128 verify above(finalHeight)
129 lock valueAmount of valueAsset with sellerProgram
131 clause settle(sellerSig: Signature, buyerSig: Signature) {
132 verify checkTxSig(sellerKey, sellerSig)
133 verify checkTxSig(buyerKey, buyerSig)
134 unlock valueAmount of valueAsset
139 const TestDefineVar = `
140 contract TestDefineVar(result: Integer) locks valueAmount of valueAsset {
141 clause LockWithMath(left: Integer, right: Integer) {
142 define calculate: Integer = left + right
143 verify left != calculate
144 verify result == calculate
145 unlock valueAmount of valueAsset
150 const TestAssignVar = `
151 contract TestAssignVar(result: Integer) locks valueAmount of valueAsset {
152 clause LockWithMath(first: Integer, second: Integer) {
153 define calculate: Integer = first
154 assign calculate = calculate + second
155 verify result == calculate
156 unlock valueAmount of valueAsset
162 contract TestSigIf(a: Integer, count:Integer) locks valueAmount of valueAsset {
163 clause check(b: Integer, c: Integer) {
170 unlock valueAmount of valueAsset
175 const TestIfAndMultiClause = `
176 contract TestIfAndMultiClause(a: Integer, cancelKey: PublicKey) locks valueAmount of valueAsset {
177 clause check(b: Integer, c: Integer) {
182 unlock valueAmount of valueAsset
184 clause cancel(sellerSig: Signature) {
185 verify checkTxSig(cancelKey, sellerSig)
186 unlock valueAmount of valueAsset
191 const TestIfNesting = `
192 contract TestIfNesting(a: Integer, count:Integer) locks valueAmount of valueAsset {
193 clause check(b: Integer, c: Integer, d: Integer) {
204 unlock valueAmount of valueAsset
206 clause cancel(e: Integer, f: Integer) {
212 unlock valueAmount of valueAsset
217 const TestConstantMath = `
218 contract TestConstantMath(result: Integer, hashByte: Hash, hashStr: Hash, outcome: Boolean) locks valueAmount of valueAsset {
219 clause calculation(left: Integer, right: Integer, boolResult: Boolean) {
220 verify result == left + right + 10
221 verify hashByte == sha3(0x31323330)
222 verify hashStr == sha3('string')
224 verify boolResult && (result == left + 20)
225 unlock valueAmount of valueAsset
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
240 func TestCompile(t *testing.T) {
257 "LockWithPublicKeyHash",
264 "537a547a526bae71557a536c7cad",
274 "547a6413000000007b7b51547ac1631a000000547a547aae7cac",
279 "537a641a000000537a7cae7cac6900c3c251557ac16328000000537a7cae7cac6900c3c251547ac1",
282 "CollateralizedLoan",
284 "557a641b000000007b7b51557ac16951c3c251557ac163260000007bcd9f6900c3c251567ac1",
294 "557a6432000000557a5479ae7cac6900c3c25100597a89587a89587a89587a89557a890274787e008901c07ec1633a000000007b537a51567ac1",
297 "CallOptionWithSettlement",
298 CallOptionWithSettlement,
299 "567a76529c64360000006425000000557acda06971ae7cac69007c7b51547ac16346000000557acd9f6900c3c251567ac1634600000075577a547aae7cac69557a547aae7cac",
304 "52797b937b7887916987",
314 "53797b879169765379a09161641c00000052795279a0696321000000765279a069",
317 "TestIfAndMultiClause",
318 TestIfAndMultiClause,
319 "7b641f0000007087916976547aa09161641a000000765379a06963240000007b7bae7cac",
324 "7b644400000054795279879169765579a09161643500000052795479a091616429000000765379a06952795579879169633a000000765479a06953797b8791635c0000007654798791695279a091616459000000527978a0697d8791",
329 "765779577a935a93887c0431323330aa887c06737472696e67aa887c91697b011493879a",
334 "5279557aac697c7bac",
338 for _, c := range cases {
339 t.Run(c.name, func(t *testing.T) {
340 r := strings.NewReader(c.contract)
341 compiled, err := Compile(r)
346 contract := compiled[len(compiled)-1]
347 got := []byte(contract.Body)
349 want, err := hex.DecodeString(c.want)
354 if string(got) != string(want) {
355 t.Errorf("%s got %s\nwant %s", c.name, hex.EncodeToString(got), hex.EncodeToString(want))