9 "github.com/equity/compiler"
10 equ "github.com/equity/equity/util"
11 "github.com/spf13/cobra"
13 "github.com/shuttle/swap"
17 // deploy contract arguments
18 deployTradeoffCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
19 deployTradeoffCmd.PersistentFlags().StringVar(&assetRequested, "assetRequested", "", "tradeoff contract paramenter with requested assetID")
20 deployTradeoffCmd.PersistentFlags().Uint64Var(&amountRequested, "amountRequested", 0, "tradeoff contract paramenter with requested amount")
21 deployTradeoffCmd.PersistentFlags().StringVar(&seller, "seller", "", "tradeoff contract paramenter with seller control-program")
22 deployTradeoffCmd.PersistentFlags().StringVar(&cancelKey, "cancelKey", "", "tradeoff contract paramenter with seller pubkey for cancelling the contract")
23 deployTradeoffCmd.PersistentFlags().StringVar(&assetLocked, "assetLocked", "", "tradeoff contract locked value with assetID")
24 deployTradeoffCmd.PersistentFlags().Uint64Var(&amountLocked, "amountLocked", 0, "tradeoff contract locked value with amount")
25 deployTradeoffCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
26 deployTradeoffCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
28 // deploy HTLC contract arguments
29 deployHTLCCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
30 deployHTLCCmd.PersistentFlags().StringVar(&senderPublicKey, "sender", "", "HTLC contract paramenter with sender PublicKey")
31 deployHTLCCmd.PersistentFlags().StringVar(&recipientPublicKey, "recipient", "", "HTLC contract paramenter with recipientPublicKey")
32 deployHTLCCmd.PersistentFlags().Uint64Var(&blockHeight, "blockHeight", 0, "HTLC contract locked value with blockHeight")
33 deployHTLCCmd.PersistentFlags().StringVar(&hash, "hash", "", "HTLC contract locked value with hash")
34 deployHTLCCmd.PersistentFlags().StringVar(&assetLocked, "assetLocked", "", "HTLC contract locked value with assetID")
35 deployHTLCCmd.PersistentFlags().Uint64Var(&amountLocked, "amountLocked", 0, "HTLC contract locked value with amount")
36 deployHTLCCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
37 deployHTLCCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
39 // call contract arguments
40 callTradeoffCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
41 callTradeoffCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
42 callTradeoffCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
44 // call HTLC contract arguments
45 callHTLCCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
46 callHTLCCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
47 callHTLCCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
49 // cancel tradeoff contract arguments
50 cancelTradeoffCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
51 cancelTradeoffCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
52 cancelTradeoffCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
54 // cancel HTLC contract arguments
55 cancelHTLCCmd.PersistentFlags().Uint64Var(&txFee, "txFee", 40000000, "contract transaction fee")
56 cancelHTLCCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
57 cancelHTLCCmd.PersistentFlags().StringVar(&port, "port", "9888", "network port")
59 // compile contract locally
60 equityCmd.PersistentFlags().BoolVar(&bin, strBin, false, "Binary of the contracts in hex.")
61 equityCmd.PersistentFlags().BoolVar(&shift, strShift, false, "Function shift of the contracts.")
62 equityCmd.PersistentFlags().BoolVar(&instance, strInstance, false, "Object of the Instantiated contracts.")
63 equityCmd.PersistentFlags().BoolVar(&ast, strAst, false, "AST of the contracts.")
64 equityCmd.PersistentFlags().BoolVar(&version, strVersion, false, "Version of equity compiler.")
66 // build deploy contract tx
67 buildTxCmd.PersistentFlags().StringVar(&ip, "ip", "127.0.0.1", "network address")
68 buildTxCmd.PersistentFlags().StringVar(&port, "port", "3000", "network port")
76 // contract paramenters
78 amountRequested = uint64(0)
82 // contract locked value
84 amountLocked = uint64(0)
86 // unlock contract paramenters
93 recipientPublicKey = ""
94 blockHeight = uint64(0)
100 strBin string = "bin"
101 strShift string = "shift"
102 strInstance string = "instance"
103 strAst string = "ast"
104 strVersion string = "version"
115 var deployTradeoffCmd = &cobra.Command{
116 Use: "deployTradeoff <accountID> <password> [contract flags(paramenters and locked value)] [txFee flag] [URL flags(ip and port)]",
117 Short: "deploy tradeoff contract",
118 Args: cobra.ExactArgs(2),
119 Run: func(cmd *cobra.Command, args []string) {
120 accountInfo := swap.AccountInfo{
125 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 {
126 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
130 contractArgs := swap.ContractArgs{
131 AssetAmount: swap.AssetAmount{
132 Asset: assetRequested,
133 Amount: amountRequested,
136 CancelKey: cancelKey,
138 if len(contractArgs.Asset) == 0 || contractArgs.Amount == uint64(0) || len(contractArgs.Seller) == 0 || len(contractArgs.CancelKey) == 0 {
139 fmt.Println("The part field of the structure ContractArgs is empty:", contractArgs)
143 contractValue := swap.AssetAmount{
145 Amount: amountLocked,
147 if len(contractValue.Asset) == 0 || contractValue.Amount == uint64(0) {
148 fmt.Println("The part field of the structure ContractValue AssetAmount is empty:", contractValue)
152 server := &swap.Server{
157 contractUTXOID, err := swap.DeployTradeoffContract(server, accountInfo, contractArgs, contractValue)
162 fmt.Println("--> contractUTXOID:", contractUTXOID)
166 var buildTxCmd = &cobra.Command{
167 Use: "build <guid> <outputID> <lockedAsset> <contractProgram> <lockedAmount> [URL flags(ip and port)]",
168 Short: "build contract",
169 Args: cobra.ExactArgs(5),
170 Run: func(cmd *cobra.Command, args []string) {
173 fmt.Println("The part field of guid is invalid:", guid)
178 if len(outputID) != 64 {
179 fmt.Println("The part field of outputID is invalid:", outputID)
183 lockedAsset := args[2]
184 if len(lockedAsset) != 64 {
185 fmt.Println("The part field of lockedAsset is invalid:", lockedAsset)
189 contractProgram := args[3]
190 if len(contractProgram) == 0 {
191 fmt.Println("The part field of contractProgram is invalid:", contractProgram)
195 lockedAmount, err := swap.ParseUint64(args[4])
197 fmt.Println("parse locked amount err:", err)
201 server := &swap.Server{
206 res, err := swap.BuildTx(server, guid, outputID, lockedAsset, contractProgram, lockedAmount)
208 fmt.Println("build tx err:", err)
212 fmt.Println("build tx result:", res)
216 var callTradeoffCmd = &cobra.Command{
217 Use: "callTradeoff <accountID> <password> <buyer-program> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
218 Short: "call tradeoff contract for asset swapping",
219 Args: cobra.ExactArgs(4),
220 Run: func(cmd *cobra.Command, args []string) {
221 accountInfo := swap.AccountInfo{
227 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 || len(accountInfo.Receiver) == 0 {
228 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
232 contractUTXOID := args[3]
233 if len(contractUTXOID) == 0 {
234 fmt.Println("contract utxoID is empty:", contractUTXOID)
238 server := &swap.Server{
243 txID, err := swap.CallTradeoffContract(server, accountInfo, contractUTXOID)
248 fmt.Println("--> txID:", txID)
252 var cancelTradeoffCmd = &cobra.Command{
253 Use: "cancelTradeoff <accountID> <password> <redeem-program> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
254 Short: "cancel tradeoff contract for asset swapping",
255 Args: cobra.ExactArgs(4),
256 Run: func(cmd *cobra.Command, args []string) {
257 accountInfo := swap.AccountInfo{
263 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 || len(accountInfo.Receiver) == 0 {
264 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
268 contractUTXOID := args[3]
269 if len(contractUTXOID) == 0 {
270 fmt.Println("contract utxoID is empty:", contractUTXOID)
274 server := &swap.Server{
279 txID, err := swap.CancelTradeoffContract(server, accountInfo, contractUTXOID)
284 fmt.Println("--> txID:", txID)
288 var deployHTLCCmd = &cobra.Command{
289 Use: "deployHTLC <accountID> <password> [contract flags(paramenters and locked value)] [txFee flag] [URL flags(ip and port)]",
290 Short: "deploy HTLC contract",
291 Args: cobra.ExactArgs(2),
292 Run: func(cmd *cobra.Command, args []string) {
293 account := swap.AccountInfo{
298 if len(account.AccountID) == 0 || len(account.Password) == 0 {
299 fmt.Println("The part field of the structure AccountInfo is empty:", account)
303 contractArgs := swap.HTLCContractArgs{
304 SenderPublicKey: senderPublicKey,
305 RecipientPublicKey: recipientPublicKey,
306 BlockHeight: blockHeight,
309 if len(contractArgs.SenderPublicKey) == 0 || len(contractArgs.RecipientPublicKey) == 0 || contractArgs.BlockHeight == uint64(0) || len(contractArgs.Hash) == 0 {
310 fmt.Println("The part field of the structure ContractArgs is empty:", contractArgs)
314 contractValue := swap.AssetAmount{
316 Amount: amountLocked,
318 if len(contractValue.Asset) == 0 || contractValue.Amount == uint64(0) {
319 fmt.Println("The part field of the structure ContractValue AssetAmount is empty:", contractValue)
323 server := &swap.Server{
328 contractUTXOID, err := swap.DeployHTLCContract(server, account, contractValue, contractArgs)
333 fmt.Println("--> contractUTXOID:", contractUTXOID)
337 var callHTLCCmd = &cobra.Command{
338 Use: "callHTLC <accountID> <password> <buyer-program> <preimage> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
339 Short: "call HTLC contract for asset swapping",
340 Args: cobra.ExactArgs(5),
341 Run: func(cmd *cobra.Command, args []string) {
342 account := swap.AccountInfo{
348 if len(account.AccountID) == 0 || len(account.Password) == 0 || len(account.Receiver) == 0 {
349 fmt.Println("The part field of the structure Account is empty:", account)
353 contractUTXOID := args[4]
354 if len(contractUTXOID) == 0 {
355 fmt.Println("contract utxoID is empty:", contractUTXOID)
360 server := &swap.Server{
364 txID, err := swap.CallHTLCContract(server, account, contractUTXOID, preimage)
369 fmt.Println("--> txID:", txID)
373 var cancelHTLCCmd = &cobra.Command{
374 Use: "cancelHTLC <accountID> <password> <redeem-program> <contractUTXOID> [txFee flag] [URL flags(ip and port)]",
375 Short: "cancel HTLC contract for asset swapping",
376 Args: cobra.ExactArgs(4),
377 Run: func(cmd *cobra.Command, args []string) {
378 accountInfo := swap.AccountInfo{
384 if len(accountInfo.AccountID) == 0 || len(accountInfo.Password) == 0 || len(accountInfo.Receiver) == 0 {
385 fmt.Println("The part field of the structure AccountInfo is empty:", accountInfo)
389 contractUTXOID := args[3]
390 if len(contractUTXOID) == 0 {
391 fmt.Println("contract utxoID is empty:", contractUTXOID)
395 server := &swap.Server{
400 txID, err := swap.CancelHTLCContract(server, accountInfo, contractUTXOID)
405 fmt.Println("--> txID:", txID)
409 var equityCmd = &cobra.Command{
410 Use: "equity <input_file>",
411 Short: "equity commandline compiler",
412 Example: "equity contract_name [contract_args...] --bin --instance",
413 Args: cobra.RangeArgs(0, 100),
414 Run: func(cmd *cobra.Command, args []string) {
416 version := compiler.VersionWithCommit(compiler.GitCommit)
417 fmt.Println("equity, the equity compiler commandline interface")
418 fmt.Println("Version:", version)
427 if err := handleCompiled(args); err != nil {
433 func handleCompiled(args []string) error {
434 contractFile, err := os.Open(args[0])
436 fmt.Printf("An error [%v] occurred on opening the file, please check whether the file exists or can be accessed.\n", err)
439 defer contractFile.Close()
441 reader := bufio.NewReader(contractFile)
442 contracts, err := compiler.Compile(reader)
444 fmt.Println("Compile contract failed:", err)
448 // Print the result for all contracts
449 for i, contract := range contracts {
450 fmt.Printf("======= %v =======\n", contract.Name)
452 fmt.Println("Binary:")
453 fmt.Printf("%v\n\n", hex.EncodeToString(contract.Body))
457 fmt.Println("Clause shift:")
458 clauseMap, err := equ.Shift(contract)
460 fmt.Println("Statistics contract clause shift error:", err)
464 for clause, shift := range clauseMap {
465 fmt.Printf(" %s: %v\n", clause, shift)
467 fmt.Printf("\nNOTE: \n If the contract contains only one clause, Users don't need clause selector when unlock contract." +
468 "\n Furthermore, there is no signification for ending clause shift except for display.\n\n")
472 if i != len(contracts)-1 {
476 fmt.Println("Instantiated program:")
477 if len(args)-1 < len(contract.Params) {
478 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))
479 usage := fmt.Sprintf("Usage:\n equity %s", args[0])
480 for _, param := range contract.Params {
481 usage = usage + " <" + param.Name + ">"
483 fmt.Printf("%s\n\n", usage)
487 contractArgs, err := equ.ConvertArguments(contract, args[1:len(contract.Params)+1])
489 fmt.Println("Convert arguments into contract parameters error:", err)
493 instantProg, err := equ.InstantiateContract(contract, contractArgs)
495 fmt.Println("Instantiate contract error:", err)
498 fmt.Printf("%v\n\n", hex.EncodeToString(instantProg))
503 rawData, err := equ.JSONMarshal(contract, true)
505 fmt.Println("Marshal the struct of contract to json error:", err)
508 fmt.Println(string(rawData))