10 "github.com/equity/compiler"
11 equ "github.com/equity/equity/util"
12 "github.com/spf13/cobra"
14 "github.com/shuttle/swap"
18 // deploy contract arguments
19 deployTradeoffCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
20 deployTradeoffCmd.PersistentFlags().StringVar(&assetRequested, "assetRequested", "", "tradeoff contract paramenter with requested assetID")
21 deployTradeoffCmd.PersistentFlags().Uint64Var(&amountRequested, "amountRequested", 0, "tradeoff contract paramenter with requested amount")
22 deployTradeoffCmd.PersistentFlags().StringVar(&seller, "seller", "", "tradeoff contract paramenter with seller control-program")
23 deployTradeoffCmd.PersistentFlags().StringVar(&cancelKey, "cancelKey", "", "tradeoff contract paramenter with seller pubkey for cancelling the contract")
24 deployTradeoffCmd.PersistentFlags().StringVar(&assetLocked, "assetLocked", "", "tradeoff contract locked value with assetID")
25 deployTradeoffCmd.PersistentFlags().Uint64Var(&amountLocked, "amountLocked", 0, "tradeoff contract locked value with amount")
26 deployTradeoffCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
27 deployTradeoffCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
29 // deploy HTLC contract arguments
30 deployHTLCCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
31 deployHTLCCmd.PersistentFlags().StringVar(&senderPublicKey, "sender", "", "HTLC contract paramenter with sender PublicKey")
32 deployHTLCCmd.PersistentFlags().StringVar(&recipientPublicKey, "recipient", "", "HTLC contract paramenter with recipientPublicKey")
33 deployHTLCCmd.PersistentFlags().Uint64Var(&blockHeight, "blockHeight", 0, "HTLC contract locked value with blockHeight")
34 deployHTLCCmd.PersistentFlags().StringVar(&hash, "hash", "", "HTLC contract locked value with hash")
35 deployHTLCCmd.PersistentFlags().StringVar(&assetLocked, "assetLocked", "", "HTLC contract locked value with assetID")
36 deployHTLCCmd.PersistentFlags().Uint64Var(&amountLocked, "amountLocked", 0, "HTLC contract locked value with amount")
37 deployHTLCCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
38 deployHTLCCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
40 // call contract arguments
41 callTradeoffCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
42 callTradeoffCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
43 callTradeoffCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
45 // call HTLC contract arguments
46 callHTLCCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
47 callHTLCCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
48 callHTLCCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
50 // cancel tradeoff contract arguments
51 cancelTradeoffCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
52 cancelTradeoffCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
53 cancelTradeoffCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
55 // cancel HTLC contract arguments
56 cancelHTLCCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
57 cancelHTLCCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
58 cancelHTLCCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
60 // compile contract locally
61 equityCmd.PersistentFlags().BoolVar(&bin, strBin, false, "Binary of the contracts in hex.")
62 equityCmd.PersistentFlags().BoolVar(&shift, strShift, false, "Function shift of the contracts.")
63 equityCmd.PersistentFlags().BoolVar(&instance, strInstance, false, "Object of the Instantiated contracts.")
64 equityCmd.PersistentFlags().BoolVar(&ast, strAst, false, "AST of the contracts.")
65 equityCmd.PersistentFlags().BoolVar(&version, strVersion, false, "Version of equity compiler.")
67 // build deploy contract tx
68 buildTxCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
69 buildTxCmd.PersistentFlags().StringVar(&port, "port", "3000", "network port")
77 // contract paramenters
79 amountRequested = uint64(0)
83 // contract locked value
85 amountLocked = uint64(0)
87 // unlock contract paramenters
94 recipientPublicKey = ""
95 blockHeight = uint64(0)
101 strBin string = "bin"
102 strShift string = "shift"
103 strInstance string = "instance"
104 strAst string = "ast"
105 strVersion string = "version"
116 var deployTradeoffCmd = &cobra.Command{
117 Use: "deployTradeoff <accountID> <password> [contract flags(paramenters and locked value)] [txFee flag] [URL flags(ip and port)]",
118 Short: "deploy tradeoff contract",
119 Args: cobra.ExactArgs(2),
120 Run: func(cmd *cobra.Command, args []string) {
121 accountInfo := swap.AccountInfo{
126 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 {
127 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
131 contractArgs := swap.ContractArgs{
132 AssetAmount: swap.AssetAmount{
133 Asset: assetRequested,
134 Amount: amountRequested,
137 CancelKey: cancelKey,
139 if len(contractArgs.Asset) == 0 || contractArgs.Amount == uint64(0) || len(contractArgs.Seller) == 0 || len(contractArgs.CancelKey) == 0 {
140 fmt.Println("The part field of the structure ContractArgs is empty:", contractArgs)
144 contractValue := swap.AssetAmount{
146 Amount: amountLocked,
148 if len(contractValue.Asset) == 0 || contractValue.Amount == uint64(0) {
149 fmt.Println("The part field of the structure ContractValue AssetAmount is empty:", contractValue)
153 server := &swap.Server{
158 contractUTXOID, err := swap.DeployTradeoffContract(server, accountInfo, contractArgs, contractValue)
163 fmt.Println("--> contractUTXOID:", contractUTXOID)
167 var buildTxCmd = &cobra.Command{
168 Use: "build <guid> <outputID> <lockedAsset> <contractProgram> <lockedAmount> [URL flags(ip and port)]",
169 Short: "build contract",
170 Args: cobra.ExactArgs(5),
171 Run: func(cmd *cobra.Command, args []string) {
174 fmt.Println("The part field of guid is invalid:", guid)
179 if _, err := hex.DecodeString(outputID); err != nil || len(outputID) != 64 {
180 fmt.Println("The part field of outputID is invalid:", outputID)
184 lockedAsset := args[2]
185 if _, err := hex.DecodeString(lockedAsset); err != nil || len(lockedAsset) != 64 {
186 fmt.Println("The part field of lockedAsset is invalid:", lockedAsset)
190 contractProgram := args[3]
191 if _, err := hex.DecodeString(contractProgram); err != nil || len(contractProgram) == 0 {
192 fmt.Println("The part field of contractProgram is invalid:", contractProgram)
196 lockedAmount, err := strconv.ParseUint(args[4], 10, 64)
198 fmt.Println("parse locked amount err:", err)
202 server := &swap.Server{
207 res, err := swap.BuildTx(server, guid, outputID, lockedAsset, contractProgram, lockedAmount)
209 fmt.Println("build tx err:", err)
213 fmt.Println("build tx result:", res)
217 var callTradeoffCmd = &cobra.Command{
218 Use: "callTradeoff <accountID> <password> <buyer-program> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
219 Short: "call tradeoff contract for asset swapping",
220 Args: cobra.ExactArgs(4),
221 Run: func(cmd *cobra.Command, args []string) {
222 accountInfo := swap.AccountInfo{
228 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 || len(accountInfo.Receiver) == 0 {
229 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
233 contractUTXOID := args[3]
234 if len(contractUTXOID) == 0 {
235 fmt.Println("contract utxoID is empty:", contractUTXOID)
239 server := &swap.Server{
244 txID, err := swap.CallTradeoffContract(server, accountInfo, contractUTXOID)
249 fmt.Println("--> txID:", txID)
253 var cancelTradeoffCmd = &cobra.Command{
254 Use: "cancelTradeoff <accountID> <password> <redeem-program> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
255 Short: "cancel tradeoff contract for asset swapping",
256 Args: cobra.ExactArgs(4),
257 Run: func(cmd *cobra.Command, args []string) {
258 accountInfo := swap.AccountInfo{
264 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 || len(accountInfo.Receiver) == 0 {
265 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
269 contractUTXOID := args[3]
270 if len(contractUTXOID) == 0 {
271 fmt.Println("contract utxoID is empty:", contractUTXOID)
275 server := &swap.Server{
280 txID, err := swap.CancelTradeoffContract(server, accountInfo, contractUTXOID)
285 fmt.Println("--> txID:", txID)
289 var deployHTLCCmd = &cobra.Command{
290 Use: "deployHTLC <accountID> <password> [contract flags(paramenters and locked value)] [txFee flag] [URL flags(ip and port)]",
291 Short: "deploy HTLC contract",
292 Args: cobra.ExactArgs(2),
293 Run: func(cmd *cobra.Command, args []string) {
294 account := swap.AccountInfo{
299 if len(account.AccountID) == 0 || len(account.Password) == 0 {
300 fmt.Println("The part field of the structure AccountInfo is empty:", account)
304 contractArgs := swap.HTLCContractArgs{
305 SenderPublicKey: senderPublicKey,
306 RecipientPublicKey: recipientPublicKey,
307 BlockHeight: blockHeight,
310 if len(contractArgs.SenderPublicKey) == 0 || len(contractArgs.RecipientPublicKey) == 0 || contractArgs.BlockHeight == uint64(0) || len(contractArgs.Hash) == 0 {
311 fmt.Println("The part field of the structure ContractArgs is empty:", contractArgs)
315 contractValue := swap.AssetAmount{
317 Amount: amountLocked,
319 if len(contractValue.Asset) == 0 || contractValue.Amount == uint64(0) {
320 fmt.Println("The part field of the structure ContractValue AssetAmount is empty:", contractValue)
324 server := &swap.Server{
329 contractUTXOID, err := swap.DeployHTLCContract(server, account, contractValue, contractArgs)
334 fmt.Println("--> contractUTXOID:", contractUTXOID)
338 var callHTLCCmd = &cobra.Command{
339 Use: "callHTLC <accountID> <password> <buyer-program> <preimage> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
340 Short: "call HTLC contract for asset swapping",
341 Args: cobra.ExactArgs(5),
342 Run: func(cmd *cobra.Command, args []string) {
343 account := swap.AccountInfo{
349 if len(account.AccountID) == 0 || len(account.Password) == 0 || len(account.Receiver) == 0 {
350 fmt.Println("The part field of the structure Account is empty:", account)
354 contractUTXOID := args[4]
355 if len(contractUTXOID) == 0 {
356 fmt.Println("contract utxoID is empty:", contractUTXOID)
361 server := &swap.Server{
365 txID, err := swap.CallHTLCContract(server, account, contractUTXOID, preimage)
370 fmt.Println("--> txID:", txID)
374 var cancelHTLCCmd = &cobra.Command{
375 Use: "cancelHTLC <accountID> <password> <redeem-program> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
376 Short: "cancel HTLC contract for asset swapping",
377 Args: cobra.ExactArgs(4),
378 Run: func(cmd *cobra.Command, args []string) {
379 accountInfo := swap.AccountInfo{
385 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 || len(accountInfo.Receiver) == 0 {
386 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
390 contractUTXOID := args[3]
391 if len(contractUTXOID) == 0 {
392 fmt.Println("contract utxoID is empty:", contractUTXOID)
396 server := &swap.Server{
401 txID, err := swap.CancelHTLCContract(server, accountInfo, contractUTXOID)
406 fmt.Println("--> txID:", txID)
410 var equityCmd = &cobra.Command{
411 Use: "equity <input_file>",
412 Short: "equity commandline compiler",
413 Example: "equity contract_name [contract_args...] --bin --instance",
414 Args: cobra.RangeArgs(0, 100),
415 Run: func(cmd *cobra.Command, args []string) {
417 version := compiler.VersionWithCommit(compiler.GitCommit)
418 fmt.Println("equity, the equity compiler commandline interface")
419 fmt.Println("Version:", version)
428 if err := handleCompiled(args); err != nil {
434 func handleCompiled(args []string) error {
435 contractFile, err := os.Open(args[0])
437 fmt.Printf("An error [%v] occurred on opening the file, please check whether the file exists or can be accessed.\n", err)
440 defer contractFile.Close()
442 reader := bufio.NewReader(contractFile)
443 contracts, err := compiler.Compile(reader)
445 fmt.Println("Compile contract failed:", err)
449 // Print the result for all contracts
450 for i, contract := range contracts {
451 fmt.Printf("======= %v =======\n", contract.Name)
453 fmt.Println("Binary:")
454 fmt.Printf("%v\n\n", hex.EncodeToString(contract.Body))
458 fmt.Println("Clause shift:")
459 clauseMap, err := equ.Shift(contract)
461 fmt.Println("Statistics contract clause shift error:", err)
465 for clause, shift := range clauseMap {
466 fmt.Printf(" %s: %v\n", clause, shift)
468 fmt.Printf("\nNOTE: \n If the contract contains only one clause, Users don't need clause selector when unlock contract." +
469 "\n Furthermore, there is no signification for ending clause shift except for display.\n\n")
473 if i != len(contracts)-1 {
477 fmt.Println("Instantiated program:")
478 if len(args)-1 < len(contract.Params) {
479 fmt.Printf("Error: The number of input arguments %d is less than the number of contract parameters %d\n", len(args)-1, len(contract.Params))
480 usage := fmt.Sprintf("Usage:\n equity %s", args[0])
481 for _, param := range contract.Params {
482 usage = usage + " <" + param.Name + ">"
484 fmt.Printf("%s\n\n", usage)
488 contractArgs, err := equ.ConvertArguments(contract, args[1:len(contract.Params)+1])
490 fmt.Println("Convert arguments into contract parameters error:", err)
494 instantProg, err := equ.InstantiateContract(contract, contractArgs)
496 fmt.Println("Instantiate contract error:", err)
499 fmt.Printf("%v\n\n", hex.EncodeToString(instantProg))
504 rawData, err := equ.JSONMarshal(contract, true)
506 fmt.Println("Marshal the struct of contract to json error:", err)
509 fmt.Println(string(rawData))