github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/cmd/bytomcli/commands/template.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 6 "github.com/bytom/bytom/errors" 7 ) 8 9 const ( 10 // contract TradeOffer's clause 11 clauseTrade = "00000000" 12 clauseCancel = "13000000" 13 tradeOfferEnding = "1a000000" 14 15 // contract Escrow's clause 16 clauseApprove = "00000000" 17 clauseReject = "1a000000" 18 escrowEnding = "28000000" 19 20 // contract LoanCollateral's clause 21 clauseRepay = "00000000" 22 clauseDefault = "1b000000" 23 loanCollateralEnding = "26000000" 24 25 // contract CallOption's clause 26 clauseExercise string = "00000000" 27 clauseExpire string = "20000000" 28 callOptionEnding string = "2c000000" 29 ) 30 31 var ( 32 errBadContractArguments = errors.New("bad contract arguments") 33 ) 34 35 // common receiver template, the clause takes only one parameter without Signature in the contract that contains only one clause, 36 // or the clause takes no parameters in the contract with multiple clauses. In addition, clause's statement like "lock payment with program" or "unlock value" 37 var buildCommonRecvReqFmt = ` 38 {"actions": [ 39 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}]}, 40 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 41 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": %s, "account_id": "%s"} 42 ]}` 43 44 var buildCommonRecvReqFmtByAlias = ` 45 {"actions": [ 46 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}]}, 47 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 48 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"} 49 ]}` 50 51 // contract is LockWithPublicKey 52 var buildLockWithPublicKeyReqFmt = ` 53 {"actions": [ 54 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}]}, 55 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 56 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": %s, "account_id": "%s"} 57 ]}` 58 59 var buildLockWithPublicKeyReqFmtByAlias = ` 60 {"actions": [ 61 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}]}, 62 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 63 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"} 64 ]}` 65 66 // contract is LockWithMultiSig 67 var buildLockWithMultiSigReqFmt = ` 68 {"actions": [ 69 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 70 {"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}]}, 71 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 72 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": %s, "account_id": "%s"} 73 ]}` 74 75 var buildLockWithMultiSigReqFmtByAlias = ` 76 {"actions": [ 77 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 78 {"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}]}, 79 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 80 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"} 81 ]}` 82 83 // contract is LockWithPublicKeyHash 84 var buildLockWithPublicKeyHashReqFmt = ` 85 {"actions": [ 86 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}, 87 {"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}]}, 88 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 89 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": %s, "account_id": "%s"} 90 ]}` 91 92 var buildLockWithPublicKeyHashReqFmtByAlias = ` 93 {"actions": [ 94 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}, 95 {"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}]}, 96 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 97 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"} 98 ]}` 99 100 // contract is TradeOffer's clause trade, the code of clause contains only two statement with "lock payment with program" and "unlock value" 101 var buildTradeOfferClauseTradeReqFmt = ` 102 {"actions": [ 103 {"type": "spend_account_unspent_output", "output_id":"%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}]}, 104 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 105 {"type": "spend_account", "asset_id": "%s", "amount": %s, "account_id": "%s"}, 106 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"}, 107 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"} 108 ]}` 109 110 var buildTradeOfferClauseTradeReqFmtByAlias = ` 111 {"actions": [ 112 {"type": "spend_account_unspent_output", "output_id":"%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}]}, 113 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 114 {"type": "spend_account", "asset_alias": "%s", "amount": %s, "account_alias": "%s"}, 115 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"}, 116 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"} 117 ]}` 118 119 // contract is TradeOffer's clause cancel 120 var buildTradeOfferClauseCancelReqFmt = ` 121 {"actions": [ 122 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 123 {"type": "data", "raw_data": {"value": "%s"}}]}, 124 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 125 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": %s, "account_id": "%s"} 126 ]}` 127 128 var buildTradeOfferClauseCancelReqFmtByAlias = ` 129 {"actions": [ 130 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 131 {"type": "data", "raw_data": {"value": "%s"}}]}, 132 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 133 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"} 134 ]}` 135 136 // contract is Escrow 137 var buildEscrowReqFmt = ` 138 {"actions": [ 139 {"type": "spend_account_unspent_output", "output_id": "%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 140 {"type": "data", "raw_data": {"value": "%s"}}]}, 141 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 142 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"} 143 ]}` 144 145 var buildEscrowReqFmtByAlias = ` 146 {"actions": [ 147 {"type": "spend_account_unspent_output", "output_id":"%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 148 {"type": "data", "raw_data": {"value": "%s"}}]}, 149 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 150 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"} 151 ]}` 152 153 // contract is LoanCollateral's clause repay, the code of clause contains only two statement with "lock payment with program" and "lock value with control_program" 154 var buildLoanCollateralClauseRepayReqFmt = ` 155 {"actions": [ 156 {"type": "spend_account_unspent_output", "output_id":"%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}]}, 157 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 158 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 159 {"type": "spend_account", "asset_id": "%s", "amount": %s, "account_id": "%s"}, 160 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"} 161 ]}` 162 163 var buildLoanCollateralClauseRepayReqFmtByAlias = ` 164 {"actions": [ 165 {"type": "spend_account_unspent_output", "output_id":"%s", "arguments": [{"type": "data", "raw_data": {"value": "%s"}}]}, 166 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 167 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 168 {"type": "spend_account", "asset_alias": "%s", "amount": %s, "account_alias": "%s"}, 169 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"} 170 ]}` 171 172 // contract is CallOption's clause exercise, the code of clause contains only two statement with "lock payment with program" and "unlock value" 173 var buildCallOptionClauseExerciseReqFmt = ` 174 {"actions": [ 175 {"type": "spend_account_unspent_output", "output_id":"%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 176 {"type": "data", "raw_data": {"value": "%s"}}]}, 177 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}, 178 {"type": "spend_account", "asset_id": "%s", "amount": %s, "account_id": "%s"}, 179 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"}, 180 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"} 181 ]}` 182 183 var buildCallOptionClauseExerciseReqFmtByAlias = ` 184 {"actions": [ 185 {"type": "spend_account_unspent_output", "output_id":"%s", "arguments": [{"type": "raw_tx_signature", "raw_data": {"xpub": "%s", "derivation_path": ["%s", "%s"]}}, 186 {"type": "data", "raw_data": {"value": "%s"}}]}, 187 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}, 188 {"type": "spend_account", "asset_alias": "%s", "amount": %s, "account_alias": "%s"}, 189 {"type": "spend_account", "asset_alias": "BTM", "amount": %s, "account_alias": "%s"}, 190 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"} 191 ]}` 192 193 // contract arguments 194 type baseContractArg struct { 195 accountInfo string 196 assetInfo string 197 amount string 198 alias bool 199 program string 200 btmGas string 201 outputID string 202 } 203 204 type basePubInfo struct { 205 rootPub string 206 path1 string 207 path2 string 208 } 209 210 type innerContractArg struct { 211 innerAccountInfo string 212 innerAssetInfo string 213 innerAmount string 214 innerProgram string 215 } 216 217 // addContractArgs add arguments for template contracts 218 func addContractArgs(contractName string, baseArg baseContractArg, specArgs []string, usage string) (buildReqStr string, err error) { 219 switch contractName { 220 case "LockWithPublicKey": 221 if len(specArgs) != 3 { 222 err = errors.WithDetailf(errBadContractArguments, "%s <rootPub> <path1> <path2> [flags]\n", usage) 223 return 224 } 225 226 pubInfo := basePubInfo{ 227 rootPub: specArgs[0], 228 path1: specArgs[1], 229 path2: specArgs[2], 230 } 231 buildReqStr = addLockWithPublicKeyArg(baseArg, pubInfo) 232 233 case "LockWithMultiSig": 234 if len(specArgs) != 6 { 235 err = errors.WithDetailf(errBadContractArguments, "%s <rootPub1> <path11> <path12> <rootPub2> <path21> <path22> [flags]\n", usage) 236 return 237 } 238 239 pubInfos := [2]basePubInfo{ 240 { 241 rootPub: specArgs[0], 242 path1: specArgs[1], 243 path2: specArgs[2], 244 }, 245 { 246 rootPub: specArgs[3], 247 path1: specArgs[4], 248 path2: specArgs[5], 249 }, 250 } 251 buildReqStr = addLockWithMultiSigArg(baseArg, pubInfos) 252 253 case "LockWithPublicKeyHash": 254 if len(specArgs) != 4 { 255 err = errors.WithDetailf(errBadContractArguments, "%s <pubKey> <rootPub> <path1> <path2> [flags]\n", usage) 256 return 257 } 258 259 pubkey := specArgs[0] 260 pubInfo := basePubInfo{ 261 rootPub: specArgs[1], 262 path1: specArgs[2], 263 path2: specArgs[3], 264 } 265 buildReqStr = addLockWithPublicKeyHashArg(baseArg, pubInfo, pubkey) 266 267 case "RevealPreimage": 268 if len(specArgs) != 1 { 269 err = errors.WithDetailf(errBadContractArguments, "%s <value> [flags]\n", usage) 270 return 271 } 272 273 value := specArgs[0] 274 buildReqStr = addRevealPreimageArg(baseArg, value) 275 276 case "TradeOffer": 277 switch { 278 case len(specArgs) <= 0: 279 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> (<innerAccountID|alias> <innerAssetID|alias> <innerAmount> <innerProgram>) | (<rootPub> <path1> <path2>) [flags]\n", usage) 280 case specArgs[0] == clauseTrade: 281 if len(specArgs) != 5 { 282 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <innerAccountID|alias> <innerAssetID|alias> <innerAmount> <innerProgram> [flags]\n", usage) 283 return 284 } 285 286 inner := &innerContractArg{ 287 innerAccountInfo: specArgs[1], 288 innerAssetInfo: specArgs[2], 289 innerAmount: specArgs[3], 290 innerProgram: specArgs[4], 291 } 292 buildReqStr, err = addTradeOfferArg(baseArg, clauseTrade, inner, nil) 293 294 case specArgs[0] == clauseCancel: 295 if len(specArgs) != 4 { 296 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <rootPub> <path1> <path2> [flags]\n", usage) 297 return 298 } 299 300 pubInfo := &basePubInfo{ 301 rootPub: specArgs[1], 302 path1: specArgs[2], 303 path2: specArgs[3], 304 } 305 buildReqStr, err = addTradeOfferArg(baseArg, clauseCancel, nil, pubInfo) 306 307 case specArgs[0] == tradeOfferEnding: 308 err = errors.WithDetailf(errBadContractArguments, "Clause ending was selected in contract %s, ending exit\n", contractName) 309 default: 310 err = errors.WithDetailf(errBadContractArguments, "selected clause [%s] error, contract %s's clause must in set [%s, %s, %s]\n", 311 specArgs[0], contractName, clauseTrade, clauseCancel, tradeOfferEnding) 312 } 313 314 case "Escrow": 315 switch { 316 case len(specArgs) <= 0: 317 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <rootPub> <path1> <path2> <controlProgram> [flags]\n", usage) 318 case specArgs[0] == clauseApprove || specArgs[0] == clauseReject: 319 if len(specArgs) != 5 { 320 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <rootPub> <path1> <path2> <controlProgram> [flags]\n", usage) 321 return 322 } 323 324 pubInfo := &basePubInfo{ 325 rootPub: specArgs[1], 326 path1: specArgs[2], 327 path2: specArgs[3], 328 } 329 controlProgram := specArgs[4] 330 buildReqStr, err = addEscrowArg(baseArg, specArgs[0], pubInfo, controlProgram) 331 332 case specArgs[0] == escrowEnding: 333 err = errors.WithDetailf(errBadContractArguments, "Clause ending was selected in contract %s, ending exit\n", contractName) 334 default: 335 err = errors.WithDetailf(errBadContractArguments, "selected clause [%s] error, contract %s's clause must in set [%s, %s, %s]\n", 336 specArgs[0], contractName, clauseApprove, clauseReject, escrowEnding) 337 } 338 339 case "LoanCollateral": 340 switch { 341 case len(specArgs) <= 0: 342 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> (<innerAccountID|alias> <innerAssetID|alias> <innerAmount> <innerProgram> <controlProgram>) | (<controlProgram>) [flags]\n", usage) 343 case specArgs[0] == clauseRepay: 344 if len(specArgs) != 6 { 345 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <innerAccountID|alias> <innerAssetID|alias> <innerAmount> <innerProgram> <controlProgram> [flags]\n", usage) 346 return 347 } 348 349 inner := &innerContractArg{ 350 innerAccountInfo: specArgs[1], 351 innerAssetInfo: specArgs[2], 352 innerAmount: specArgs[3], 353 innerProgram: specArgs[4], 354 } 355 controlProgram := specArgs[5] 356 buildReqStr, err = addLoanCollateralArg(baseArg, specArgs[0], inner, controlProgram) 357 358 case specArgs[0] == clauseDefault: 359 if len(specArgs) != 2 { 360 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <controlProgram> [flags]\n", usage) 361 return 362 } 363 364 controlProgram := specArgs[1] 365 buildReqStr, err = addLoanCollateralArg(baseArg, specArgs[0], nil, controlProgram) 366 367 case specArgs[0] == loanCollateralEnding: 368 err = errors.WithDetailf(errBadContractArguments, "Clause ending was selected in contract %s, ending exit\n", contractName) 369 default: 370 err = errors.WithDetailf(errBadContractArguments, "selected clause [%s] error, contract %s's clause must in set:[%s, %s, %s]\n", 371 specArgs[0], contractName, clauseRepay, clauseDefault, loanCollateralEnding) 372 } 373 374 case "CallOption": 375 switch { 376 case len(specArgs) <= 0: 377 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> (<innerAccountID|alias> <innerAssetID|alias> <innerAmount> <innerProgram> <rootPub> <path1> <path2>) | (<controlProgram>) [flags]\n", usage) 378 case specArgs[0] == clauseExercise: 379 if len(specArgs) != 8 { 380 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <innerAccountID|alias> <innerAssetID|alias> <innerAmount> <innerProgram> <rootPub> <path1> <path2> [flags]\n", usage) 381 return 382 } 383 384 inner := &innerContractArg{ 385 innerAccountInfo: specArgs[1], 386 innerAssetInfo: specArgs[2], 387 innerAmount: specArgs[3], 388 innerProgram: specArgs[4], 389 } 390 391 pubInfo := &basePubInfo{ 392 rootPub: specArgs[5], 393 path1: specArgs[6], 394 path2: specArgs[7], 395 } 396 buildReqStr, err = addCallOptionArg(baseArg, specArgs[0], inner, pubInfo, "") 397 398 case specArgs[0] == clauseExpire: 399 if len(specArgs) != 2 { 400 err = errors.WithDetailf(errBadContractArguments, "%s <clauseSelector> <controlProgram> [flags]\n", usage) 401 return 402 } 403 404 controlProgram := specArgs[1] 405 buildReqStr, err = addCallOptionArg(baseArg, specArgs[0], nil, nil, controlProgram) 406 407 case specArgs[0] == callOptionEnding: 408 err = errors.WithDetailf(errBadContractArguments, "Clause ending was selected in contract %s, ending exit\n", contractName) 409 default: 410 err = errors.WithDetailf(errBadContractArguments, "selected clause [%s] error, contract %s's clause must in set:[%s, %s, %s]\n", 411 specArgs[0], contractName, clauseExercise, clauseExpire, callOptionEnding) 412 } 413 414 default: 415 err = errors.WithDetailf(errBadContractArguments, "Invalid contract template name [%s]", contractName) 416 } 417 418 return 419 } 420 421 func addLockWithPublicKeyArg(baseArg baseContractArg, pubInfo basePubInfo) (buildReqStr string) { 422 buildReqFmt := buildLockWithPublicKeyReqFmt 423 if baseArg.alias { 424 buildReqFmt = buildLockWithPublicKeyReqFmtByAlias 425 } 426 427 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, pubInfo.rootPub, pubInfo.path1, pubInfo.path2, 428 baseArg.assetInfo, baseArg.amount, baseArg.program, baseArg.btmGas, baseArg.accountInfo) 429 430 return 431 } 432 433 func addLockWithMultiSigArg(baseArg baseContractArg, pubInfos [2]basePubInfo) (buildReqStr string) { 434 buildReqFmt := buildLockWithMultiSigReqFmt 435 if baseArg.alias { 436 buildReqFmt = buildLockWithMultiSigReqFmtByAlias 437 } 438 439 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, pubInfos[0].rootPub, pubInfos[0].path1, pubInfos[0].path2, 440 pubInfos[1].rootPub, pubInfos[1].path1, pubInfos[1].path2, 441 baseArg.assetInfo, baseArg.amount, baseArg.program, baseArg.btmGas, baseArg.accountInfo) 442 443 return 444 } 445 446 func addLockWithPublicKeyHashArg(baseArg baseContractArg, pubInfo basePubInfo, pubkey string) (buildReqStr string) { 447 buildReqFmt := buildLockWithPublicKeyHashReqFmt 448 if baseArg.alias { 449 buildReqFmt = buildLockWithPublicKeyHashReqFmtByAlias 450 } 451 452 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, pubkey, pubInfo.rootPub, pubInfo.path1, pubInfo.path2, 453 baseArg.assetInfo, baseArg.amount, baseArg.program, baseArg.btmGas, baseArg.accountInfo) 454 455 return 456 } 457 458 func addRevealPreimageArg(baseArg baseContractArg, value string) (buildReqStr string) { 459 buildReqFmt := buildCommonRecvReqFmt 460 if baseArg.alias { 461 buildReqFmt = buildCommonRecvReqFmtByAlias 462 } 463 464 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, value, 465 baseArg.assetInfo, baseArg.amount, baseArg.program, baseArg.btmGas, baseArg.accountInfo) 466 467 return 468 } 469 470 func addTradeOfferArg(baseArg baseContractArg, selector string, innerArg *innerContractArg, pubInfo *basePubInfo) (buildReqStr string, err error) { 471 switch selector { 472 case clauseTrade: 473 if innerArg == nil { 474 err = errors.New("Contract TradeOffer's clause trade argument is nil") 475 return 476 } 477 478 buildReqFmt := buildTradeOfferClauseTradeReqFmt 479 if baseArg.alias { 480 buildReqFmt = buildTradeOfferClauseTradeReqFmtByAlias 481 } 482 483 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, selector, 484 innerArg.innerAssetInfo, innerArg.innerAmount, innerArg.innerProgram, 485 innerArg.innerAssetInfo, innerArg.innerAmount, innerArg.innerAccountInfo, 486 baseArg.btmGas, baseArg.accountInfo, 487 baseArg.assetInfo, baseArg.amount, baseArg.program) 488 489 case clauseCancel: 490 if pubInfo == nil { 491 err = errors.New("Contract TradeOffer's clause cancel argument is nil") 492 return 493 } 494 495 buildReqFmt := buildTradeOfferClauseCancelReqFmt 496 if baseArg.alias { 497 buildReqFmt = buildTradeOfferClauseCancelReqFmtByAlias 498 } 499 500 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, pubInfo.rootPub, pubInfo.path1, pubInfo.path2, selector, 501 baseArg.assetInfo, baseArg.amount, baseArg.program, baseArg.btmGas, baseArg.accountInfo) 502 503 default: 504 err = errors.New("Invalid contract clause selector") 505 } 506 507 return 508 } 509 510 func addEscrowArg(baseArg baseContractArg, selector string, pubInfo *basePubInfo, controlProgram string) (buildReqStr string, err error) { 511 switch selector { 512 case clauseApprove, clauseReject: 513 if pubInfo == nil { 514 err = errors.New("Contract Escrow's clause argument is nil") 515 return 516 } 517 518 buildReqFmt := buildEscrowReqFmt 519 if baseArg.alias { 520 buildReqFmt = buildEscrowReqFmtByAlias 521 } 522 523 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, pubInfo.rootPub, pubInfo.path1, pubInfo.path2, selector, 524 baseArg.assetInfo, baseArg.amount, controlProgram, baseArg.btmGas, baseArg.accountInfo) 525 526 default: 527 err = errors.New("Invalid contract clause selector") 528 } 529 530 return 531 } 532 533 func addLoanCollateralArg(baseArg baseContractArg, selector string, innerArg *innerContractArg, controlProgram string) (buildReqStr string, err error) { 534 switch selector { 535 case clauseRepay: 536 if innerArg == nil { 537 err = errors.New("Contract LoanCollateral's clause repay argument is nil") 538 return 539 } 540 541 buildReqFmt := buildLoanCollateralClauseRepayReqFmt 542 if baseArg.alias { 543 buildReqFmt = buildLoanCollateralClauseRepayReqFmtByAlias 544 } 545 546 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, selector, 547 innerArg.innerAssetInfo, innerArg.innerAmount, innerArg.innerProgram, 548 baseArg.assetInfo, baseArg.amount, controlProgram, 549 innerArg.innerAssetInfo, innerArg.innerAmount, innerArg.innerAccountInfo, 550 baseArg.btmGas, baseArg.accountInfo) 551 552 case clauseDefault: 553 buildReqFmt := buildCommonRecvReqFmt 554 if baseArg.alias { 555 buildReqFmt = buildCommonRecvReqFmtByAlias 556 } 557 558 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, selector, 559 baseArg.assetInfo, baseArg.amount, controlProgram, baseArg.btmGas, baseArg.accountInfo) 560 561 default: 562 err = errors.New("Invalid contract clause selector") 563 } 564 565 return 566 } 567 568 func addCallOptionArg(baseArg baseContractArg, selector string, innerArg *innerContractArg, pubInfo *basePubInfo, controlProgram string) (buildReqStr string, err error) { 569 switch selector { 570 case clauseExercise: 571 if innerArg == nil || pubInfo == nil { 572 err = errors.New("Contract CallOption's clause exercise argument is nil") 573 return 574 } 575 576 buildReqFmt := buildCallOptionClauseExerciseReqFmt 577 if baseArg.alias { 578 buildReqFmt = buildCallOptionClauseExerciseReqFmtByAlias 579 } 580 581 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, pubInfo.rootPub, pubInfo.path1, pubInfo.path2, selector, 582 innerArg.innerAssetInfo, innerArg.innerAmount, innerArg.innerProgram, 583 innerArg.innerAssetInfo, innerArg.innerAmount, innerArg.innerAccountInfo, 584 baseArg.btmGas, baseArg.accountInfo, 585 baseArg.assetInfo, baseArg.amount, baseArg.program) 586 587 case clauseExpire: 588 buildReqFmt := buildCommonRecvReqFmt 589 if baseArg.alias { 590 buildReqFmt = buildCommonRecvReqFmtByAlias 591 } 592 593 buildReqStr = fmt.Sprintf(buildReqFmt, baseArg.outputID, selector, 594 baseArg.assetInfo, baseArg.amount, controlProgram, baseArg.btmGas, baseArg.accountInfo) 595 596 default: 597 err = errors.New("Invalid contract clause selector") 598 } 599 600 return 601 }