github.com/algorand/go-algorand-sdk@v1.24.0/transaction/transaction.go (about) 1 package transaction 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "fmt" 7 8 "github.com/algorand/go-algorand-sdk/crypto" 9 "github.com/algorand/go-algorand-sdk/encoding/msgpack" 10 "github.com/algorand/go-algorand-sdk/types" 11 ) 12 13 // MinTxnFee is v5 consensus params, in microAlgos 14 const MinTxnFee = 1000 15 16 // NumOfAdditionalBytesAfterSigning is the number of bytes added to a txn after signing it 17 const NumOfAdditionalBytesAfterSigning = 75 18 19 // MakePaymentTxn constructs a payment transaction using the passed parameters. 20 // `from` and `to` addresses should be checksummed, human-readable addresses 21 // fee is fee per byte as received from algod SuggestedFee API call 22 // Deprecated: next major version will use a Params object, see package future 23 func MakePaymentTxn(from, to string, fee, amount, firstRound, lastRound uint64, note []byte, closeRemainderTo, genesisID string, genesisHash []byte) (types.Transaction, error) { 24 // Decode from address 25 fromAddr, err := types.DecodeAddress(from) 26 if err != nil { 27 return types.Transaction{}, err 28 } 29 30 // Decode to address 31 toAddr, err := types.DecodeAddress(to) 32 if err != nil { 33 return types.Transaction{}, err 34 } 35 36 // Decode the CloseRemainderTo address, if present 37 var closeRemainderToAddr types.Address 38 if closeRemainderTo != "" { 39 closeRemainderToAddr, err = types.DecodeAddress(closeRemainderTo) 40 if err != nil { 41 return types.Transaction{}, err 42 } 43 } 44 45 // Decode GenesisHash 46 if len(genesisHash) == 0 { 47 return types.Transaction{}, fmt.Errorf("payment transaction must contain a genesisHash") 48 } 49 50 var gh types.Digest 51 copy(gh[:], genesisHash) 52 53 // Build the transaction 54 tx := types.Transaction{ 55 Type: types.PaymentTx, 56 Header: types.Header{ 57 Sender: fromAddr, 58 Fee: types.MicroAlgos(fee), 59 FirstValid: types.Round(firstRound), 60 LastValid: types.Round(lastRound), 61 Note: note, 62 GenesisID: genesisID, 63 GenesisHash: gh, 64 }, 65 PaymentTxnFields: types.PaymentTxnFields{ 66 Receiver: toAddr, 67 Amount: types.MicroAlgos(amount), 68 CloseRemainderTo: closeRemainderToAddr, 69 }, 70 } 71 72 // Update fee 73 eSize, err := EstimateSize(tx) 74 if err != nil { 75 return types.Transaction{}, err 76 } 77 tx.Fee = types.MicroAlgos(eSize * fee) 78 79 if tx.Fee < MinTxnFee { 80 tx.Fee = MinTxnFee 81 } 82 83 return tx, nil 84 } 85 86 // MakePaymentTxnWithFlatFee constructs a payment transaction using the passed parameters. 87 // `from` and `to` addresses should be checksummed, human-readable addresses 88 // fee is a flat fee 89 // Deprecated: next major version will use a Params object, see package future 90 func MakePaymentTxnWithFlatFee(from, to string, fee, amount, firstRound, lastRound uint64, note []byte, closeRemainderTo, genesisID string, genesisHash []byte) (types.Transaction, error) { 91 tx, err := MakePaymentTxn(from, to, fee, amount, firstRound, lastRound, note, closeRemainderTo, genesisID, genesisHash) 92 if err != nil { 93 return types.Transaction{}, err 94 } 95 tx.Fee = types.MicroAlgos(fee) 96 97 if tx.Fee < MinTxnFee { 98 tx.Fee = MinTxnFee 99 } 100 101 return tx, nil 102 } 103 104 // MakeKeyRegTxn constructs a keyreg transaction using the passed parameters. 105 // - account is a checksummed, human-readable address for which we register the given participation key. 106 // - fee is fee per byte as received from algod SuggestedFee API call. 107 // - firstRound is the first round this txn is valid (txn semantics unrelated to key registration) 108 // - lastRound is the last round this txn is valid 109 // - note is a byte array 110 // - genesis id corresponds to the id of the network 111 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 112 // KeyReg parameters: 113 // - votePK is a base64-encoded string corresponding to the root participation public key 114 // - selectionKey is a base64-encoded string corresponding to the vrf public key 115 // - voteFirst is the first round this participation key is valid 116 // - voteLast is the last round this participation key is valid 117 // - voteKeyDilution is the dilution for the 2-level participation key 118 // Deprecated: next major version will use a Params object, see package future 119 func MakeKeyRegTxn(account string, feePerByte, firstRound, lastRound uint64, note []byte, genesisID string, genesisHash string, 120 voteKey, selectionKey string, voteFirst, voteLast, voteKeyDilution uint64) (types.Transaction, error) { 121 // Decode account address 122 accountAddr, err := types.DecodeAddress(account) 123 if err != nil { 124 return types.Transaction{}, err 125 } 126 127 ghBytes, err := byte32FromBase64(genesisHash) 128 if err != nil { 129 return types.Transaction{}, err 130 } 131 132 votePKBytes, err := byte32FromBase64(voteKey) 133 if err != nil { 134 return types.Transaction{}, err 135 } 136 137 selectionPKBytes, err := byte32FromBase64(selectionKey) 138 if err != nil { 139 return types.Transaction{}, err 140 } 141 142 tx := types.Transaction{ 143 Type: types.KeyRegistrationTx, 144 Header: types.Header{ 145 Sender: accountAddr, 146 Fee: types.MicroAlgos(feePerByte), 147 FirstValid: types.Round(firstRound), 148 LastValid: types.Round(lastRound), 149 Note: note, 150 GenesisHash: types.Digest(ghBytes), 151 GenesisID: genesisID, 152 }, 153 KeyregTxnFields: types.KeyregTxnFields{ 154 VotePK: types.VotePK(votePKBytes), 155 SelectionPK: types.VRFPK(selectionPKBytes), 156 VoteFirst: types.Round(voteFirst), 157 VoteLast: types.Round(voteLast), 158 VoteKeyDilution: voteKeyDilution, 159 }, 160 } 161 162 // Update fee 163 eSize, err := EstimateSize(tx) 164 if err != nil { 165 return types.Transaction{}, err 166 } 167 tx.Fee = types.MicroAlgos(eSize * feePerByte) 168 169 if tx.Fee < MinTxnFee { 170 tx.Fee = MinTxnFee 171 } 172 173 return tx, nil 174 } 175 176 // MakeKeyRegTxnWithFlatFee constructs a keyreg transaction using the passed parameters. 177 // - account is a checksummed, human-readable address for which we register the given participation key. 178 // - fee is a flat fee 179 // - firstRound is the first round this txn is valid (txn semantics unrelated to key registration) 180 // - lastRound is the last round this txn is valid 181 // - note is a byte array 182 // - genesis id corresponds to the id of the network 183 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 184 // KeyReg parameters: 185 // - votePK is a base64-encoded string corresponding to the root participation public key 186 // - selectionKey is a base64-encoded string corresponding to the vrf public key 187 // - voteFirst is the first round this participation key is valid 188 // - voteLast is the last round this participation key is valid 189 // - voteKeyDilution is the dilution for the 2-level participation key 190 // Deprecated: next major version will use a Params object, see package future 191 func MakeKeyRegTxnWithFlatFee(account string, fee, firstRound, lastRound uint64, note []byte, genesisID string, genesisHash string, 192 voteKey, selectionKey string, voteFirst, voteLast, voteKeyDilution uint64) (types.Transaction, error) { 193 tx, err := MakeKeyRegTxn(account, fee, firstRound, lastRound, note, genesisID, genesisHash, voteKey, selectionKey, voteFirst, voteLast, voteKeyDilution) 194 if err != nil { 195 return types.Transaction{}, err 196 } 197 198 tx.Fee = types.MicroAlgos(fee) 199 200 if tx.Fee < MinTxnFee { 201 tx.Fee = MinTxnFee 202 } 203 204 return tx, nil 205 } 206 207 // MakeAssetCreateTxn constructs an asset creation transaction using the passed parameters. 208 // - account is a checksummed, human-readable address which will send the transaction. 209 // - fee is fee per byte as received from algod SuggestedFee API call. 210 // - firstRound is the first round this txn is valid (txn semantics unrelated to the asset) 211 // - lastRound is the last round this txn is valid 212 // - note is a byte array 213 // - genesis id corresponds to the id of the network 214 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 215 // Asset creation parameters: 216 // - see asset.go 217 // Deprecated: next major version will use a Params object, see package future 218 func MakeAssetCreateTxn(account string, feePerByte, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 219 total uint64, decimals uint32, defaultFrozen bool, manager, reserve, freeze, clawback string, 220 unitName, assetName, url, metadataHash string) (types.Transaction, error) { 221 var tx types.Transaction 222 var err error 223 224 if decimals > types.AssetMaxNumberOfDecimals { 225 return tx, fmt.Errorf("cannot create an asset with number of decimals %d (more than maximum %d)", decimals, types.AssetMaxNumberOfDecimals) 226 } 227 228 tx.Type = types.AssetConfigTx 229 tx.AssetParams = types.AssetParams{ 230 Total: total, 231 Decimals: decimals, 232 DefaultFrozen: defaultFrozen, 233 UnitName: unitName, 234 AssetName: assetName, 235 URL: url, 236 } 237 238 if manager != "" { 239 tx.AssetParams.Manager, err = types.DecodeAddress(manager) 240 if err != nil { 241 return tx, err 242 } 243 } 244 if reserve != "" { 245 tx.AssetParams.Reserve, err = types.DecodeAddress(reserve) 246 if err != nil { 247 return tx, err 248 } 249 } 250 if freeze != "" { 251 tx.AssetParams.Freeze, err = types.DecodeAddress(freeze) 252 if err != nil { 253 return tx, err 254 } 255 } 256 if clawback != "" { 257 tx.AssetParams.Clawback, err = types.DecodeAddress(clawback) 258 if err != nil { 259 return tx, err 260 } 261 } 262 263 if len(assetName) > types.AssetNameMaxLen { 264 return tx, fmt.Errorf("asset name too long: %d > %d", len(assetName), types.AssetNameMaxLen) 265 } 266 tx.AssetParams.AssetName = assetName 267 268 if len(url) > types.AssetURLMaxLen { 269 return tx, fmt.Errorf("asset url too long: %d > %d", len(url), types.AssetURLMaxLen) 270 } 271 tx.AssetParams.URL = url 272 273 if len(unitName) > types.AssetUnitNameMaxLen { 274 return tx, fmt.Errorf("asset unit name too long: %d > %d", len(unitName), types.AssetUnitNameMaxLen) 275 } 276 tx.AssetParams.UnitName = unitName 277 278 if len(metadataHash) > types.AssetMetadataHashLen { 279 return tx, fmt.Errorf("asset metadata hash '%s' too long: %d > %d)", metadataHash, len(metadataHash), types.AssetMetadataHashLen) 280 } 281 copy(tx.AssetParams.MetadataHash[:], []byte(metadataHash)) 282 283 // Fill in header 284 accountAddr, err := types.DecodeAddress(account) 285 if err != nil { 286 return types.Transaction{}, err 287 } 288 ghBytes, err := byte32FromBase64(genesisHash) 289 if err != nil { 290 return types.Transaction{}, err 291 } 292 tx.Header = types.Header{ 293 Sender: accountAddr, 294 Fee: types.MicroAlgos(feePerByte), 295 FirstValid: types.Round(firstRound), 296 LastValid: types.Round(lastRound), 297 GenesisHash: types.Digest(ghBytes), 298 GenesisID: genesisID, 299 Note: note, 300 } 301 302 // Update fee 303 eSize, err := EstimateSize(tx) 304 if err != nil { 305 return types.Transaction{}, err 306 } 307 tx.Fee = types.MicroAlgos(eSize * feePerByte) 308 309 if tx.Fee < MinTxnFee { 310 tx.Fee = MinTxnFee 311 } 312 313 return tx, nil 314 } 315 316 // MakeAssetConfigTxn creates a tx template for changing the 317 // key configuration of an existing asset. 318 // Important notes - 319 // * Every asset config transaction is a fresh one. No parameters will be inherited from the current config. 320 // * Once an address is set to to the empty string, IT CAN NEVER BE CHANGED AGAIN. For example, if you want to keep 321 // The current manager, you must specify its address again. 322 // Parameters - 323 // - account is a checksummed, human-readable address that will send the transaction 324 // - feePerByte is a fee per byte 325 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset config) 326 // - lastRound is the last round this txn is valid 327 // - note is an arbitrary byte array 328 // - genesis id corresponds to the id of the network 329 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 330 // - index is the asset index id 331 // - for newManager, newReserve, newFreeze, newClawback see asset.go 332 // - strictEmptyAddressChecking: if true, disallow empty admin accounts from being set (preventing accidental disable of admin features) 333 // Deprecated: next major version will use a Params object, see package future 334 func MakeAssetConfigTxn(account string, feePerByte, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 335 index uint64, newManager, newReserve, newFreeze, newClawback string, strictEmptyAddressChecking bool) (types.Transaction, error) { 336 var tx types.Transaction 337 338 if strictEmptyAddressChecking && (newManager == "" || newReserve == "" || newFreeze == "" || newClawback == "") { 339 return tx, fmt.Errorf("strict empty address checking requested but empty address supplied to one or more manager addresses") 340 } 341 342 tx.Type = types.AssetConfigTx 343 344 accountAddr, err := types.DecodeAddress(account) 345 if err != nil { 346 return tx, err 347 } 348 349 ghBytes, err := byte32FromBase64(genesisHash) 350 if err != nil { 351 return types.Transaction{}, err 352 } 353 354 tx.Header = types.Header{ 355 Sender: accountAddr, 356 Fee: types.MicroAlgos(feePerByte), 357 FirstValid: types.Round(firstRound), 358 LastValid: types.Round(lastRound), 359 GenesisHash: ghBytes, 360 GenesisID: genesisID, 361 Note: note, 362 } 363 364 tx.ConfigAsset = types.AssetIndex(index) 365 366 if newManager != "" { 367 tx.Type = types.AssetConfigTx 368 tx.AssetParams.Manager, err = types.DecodeAddress(newManager) 369 if err != nil { 370 return tx, err 371 } 372 } 373 374 if newReserve != "" { 375 tx.AssetParams.Reserve, err = types.DecodeAddress(newReserve) 376 if err != nil { 377 return tx, err 378 } 379 } 380 381 if newFreeze != "" { 382 tx.AssetParams.Freeze, err = types.DecodeAddress(newFreeze) 383 if err != nil { 384 return tx, err 385 } 386 } 387 388 if newClawback != "" { 389 tx.AssetParams.Clawback, err = types.DecodeAddress(newClawback) 390 if err != nil { 391 return tx, err 392 } 393 } 394 395 // Update fee 396 eSize, err := EstimateSize(tx) 397 if err != nil { 398 return types.Transaction{}, err 399 } 400 tx.Fee = types.MicroAlgos(eSize * feePerByte) 401 402 if tx.Fee < MinTxnFee { 403 tx.Fee = MinTxnFee 404 } 405 406 return tx, nil 407 } 408 409 // transferAssetBuilder is a helper that builds asset transfer transactions: 410 // either a normal asset transfer, or an asset revocation 411 // Deprecated: next major version will use a Params object, see package future 412 func transferAssetBuilder(account, recipient, closeAssetsTo, revocationTarget string, amount, feePerByte, 413 firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, index uint64) (types.Transaction, error) { 414 var tx types.Transaction 415 tx.Type = types.AssetTransferTx 416 417 accountAddr, err := types.DecodeAddress(account) 418 if err != nil { 419 return tx, err 420 } 421 422 ghBytes, err := byte32FromBase64(genesisHash) 423 if err != nil { 424 return types.Transaction{}, err 425 } 426 427 tx.Header = types.Header{ 428 Sender: accountAddr, 429 Fee: types.MicroAlgos(feePerByte), 430 FirstValid: types.Round(firstRound), 431 LastValid: types.Round(lastRound), 432 GenesisHash: types.Digest(ghBytes), 433 GenesisID: genesisID, 434 Note: note, 435 } 436 437 tx.XferAsset = types.AssetIndex(index) 438 439 recipientAddr, err := types.DecodeAddress(recipient) 440 if err != nil { 441 return tx, err 442 } 443 tx.AssetReceiver = recipientAddr 444 445 if closeAssetsTo != "" { 446 closeToAddr, err := types.DecodeAddress(closeAssetsTo) 447 if err != nil { 448 return tx, err 449 } 450 tx.AssetCloseTo = closeToAddr 451 } 452 453 if revocationTarget != "" { 454 revokedAddr, err := types.DecodeAddress(revocationTarget) 455 if err != nil { 456 return tx, err 457 } 458 tx.AssetSender = revokedAddr 459 } 460 461 tx.AssetAmount = amount 462 463 // Update fee 464 eSize, err := EstimateSize(tx) 465 if err != nil { 466 return types.Transaction{}, err 467 } 468 tx.Fee = types.MicroAlgos(eSize * feePerByte) 469 470 if tx.Fee < MinTxnFee { 471 tx.Fee = MinTxnFee 472 } 473 474 return tx, nil 475 } 476 477 // MakeAssetTransferTxn creates a tx for sending some asset from an asset holder to another user 478 // the recipient address must have previously issued an asset acceptance transaction for this asset 479 // - account is a checksummed, human-readable address that will send the transaction and assets 480 // - recipient is a checksummed, human-readable address what will receive the assets 481 // - closeAssetsTo is a checksummed, human-readable address that behaves as a close-to address for the asset transaction; the remaining assets not sent to recipient will be sent to closeAssetsTo. Leave blank for no close-to behavior. 482 // - amount is the number of assets to send 483 // - feePerByte is a fee per byte 484 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 485 // - lastRound is the last round this txn is valid 486 // - note is an arbitrary byte array 487 // - genesis id corresponds to the id of the network 488 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 489 // - index is the asset index 490 // Deprecated: next major version will use a Params object, see package future 491 func MakeAssetTransferTxn(account, recipient, closeAssetsTo string, amount, feePerByte, firstRound, lastRound uint64, note []byte, 492 genesisID, genesisHash string, index uint64) (types.Transaction, error) { 493 revocationTarget := "" // no asset revocation, this is normal asset transfer 494 return transferAssetBuilder(account, recipient, closeAssetsTo, revocationTarget, amount, feePerByte, firstRound, lastRound, 495 note, genesisID, genesisHash, index) 496 } 497 498 // MakeAssetAcceptanceTxn creates a tx for marking an account as willing to accept the given asset 499 // - account is a checksummed, human-readable address that will send the transaction and begin accepting the asset 500 // - feePerByte is a fee per byte 501 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 502 // - lastRound is the last round this txn is valid 503 // - note is an arbitrary byte array 504 // - genesis id corresponds to the id of the network 505 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 506 // - index is the asset index 507 // Deprecated: next major version will use a Params object, see package future 508 func MakeAssetAcceptanceTxn(account string, feePerByte, firstRound, lastRound uint64, note []byte, 509 genesisID, genesisHash string, index uint64) (types.Transaction, error) { 510 return MakeAssetTransferTxn(account, account, "", 0, 511 feePerByte, firstRound, lastRound, note, genesisID, genesisHash, index) 512 } 513 514 // MakeAssetRevocationTxn creates a tx for revoking an asset from an account and sending it to another 515 // - account is a checksummed, human-readable address; it must be the revocation manager / clawback address from the asset's parameters 516 // - target is a checksummed, human-readable address; it is the account whose assets will be revoked 517 // - recipient is a checksummed, human-readable address; it will receive the revoked assets 518 // - feePerByte is a fee per byte 519 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 520 // - lastRound is the last round this txn is valid 521 // - note is an arbitrary byte array 522 // - genesis id corresponds to the id of the network 523 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 524 // - index is the asset index 525 // Deprecated: next major version will use a Params object, see package future 526 func MakeAssetRevocationTxn(account, target, recipient string, amount, feePerByte, firstRound, lastRound uint64, note []byte, 527 genesisID, genesisHash string, index uint64) (types.Transaction, error) { 528 closeAssetsTo := "" // no close-out, this is an asset revocation 529 return transferAssetBuilder(account, recipient, closeAssetsTo, target, amount, feePerByte, firstRound, lastRound, 530 note, genesisID, genesisHash, index) 531 } 532 533 // MakeAssetDestroyTxn creates a tx template for destroying an asset, removing it from the record. 534 // All outstanding asset amount must be held by the creator, and this transaction must be issued by the asset manager. 535 // - account is a checksummed, human-readable address that will send the transaction; it also must be the asset manager 536 // - fee is a fee per byte 537 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 538 // - lastRound is the last round this txn is valid 539 // - genesis id corresponds to the id of the network 540 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 541 // - index is the asset index 542 // Deprecated: next major version will use a Params object, see package future 543 func MakeAssetDestroyTxn(account string, feePerByte, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 544 index uint64) (types.Transaction, error) { 545 // an asset destroy transaction is just a configuration transaction with AssetParams zeroed 546 tx, err := MakeAssetConfigTxn(account, feePerByte, firstRound, lastRound, note, genesisID, genesisHash, 547 index, "", "", "", "", false) 548 549 return tx, err 550 } 551 552 // MakeAssetFreezeTxn constructs a transaction that freezes or unfreezes an account's asset holdings 553 // It must be issued by the freeze address for the asset 554 // - account is a checksummed, human-readable address which will send the transaction. 555 // - fee is fee per byte as received from algod SuggestedFee API call. 556 // - firstRound is the first round this txn is valid (txn semantics unrelated to the asset) 557 // - lastRound is the last round this txn is valid 558 // - note is an optional arbitrary byte array 559 // - genesis id corresponds to the id of the network 560 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 561 // - assetIndex is the index for tracking the asset 562 // - target is the account to be frozen or unfrozen 563 // - newFreezeSetting is the new state of the target account 564 // Deprecated: next major version will use a Params object, see package future 565 func MakeAssetFreezeTxn(account string, fee, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 566 assetIndex uint64, target string, newFreezeSetting bool) (types.Transaction, error) { 567 var tx types.Transaction 568 569 tx.Type = types.AssetFreezeTx 570 571 accountAddr, err := types.DecodeAddress(account) 572 if err != nil { 573 return tx, err 574 } 575 576 ghBytes, err := byte32FromBase64(genesisHash) 577 if err != nil { 578 return types.Transaction{}, err 579 } 580 581 tx.Header = types.Header{ 582 Sender: accountAddr, 583 Fee: types.MicroAlgos(fee), 584 FirstValid: types.Round(firstRound), 585 LastValid: types.Round(lastRound), 586 GenesisHash: types.Digest(ghBytes), 587 GenesisID: genesisID, 588 Note: note, 589 } 590 591 tx.FreezeAsset = types.AssetIndex(assetIndex) 592 593 tx.FreezeAccount, err = types.DecodeAddress(target) 594 if err != nil { 595 return tx, err 596 } 597 598 tx.AssetFrozen = newFreezeSetting 599 // Update fee 600 eSize, err := EstimateSize(tx) 601 if err != nil { 602 return types.Transaction{}, err 603 } 604 tx.Fee = types.MicroAlgos(eSize * fee) 605 606 if tx.Fee < MinTxnFee { 607 tx.Fee = MinTxnFee 608 } 609 610 return tx, nil 611 } 612 613 // MakeAssetCreateTxnWithFlatFee constructs an asset creation transaction using the passed parameters. 614 // - account is a checksummed, human-readable address which will send the transaction. 615 // - fee is fee per byte as received from algod SuggestedFee API call. 616 // - firstRound is the first round this txn is valid (txn semantics unrelated to the asset) 617 // - lastRound is the last round this txn is valid 618 // - genesis id corresponds to the id of the network 619 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 620 // Asset creation parameters: 621 // - see asset.go 622 // Deprecated: next major version will use a Params object, see package future 623 func MakeAssetCreateTxnWithFlatFee(account string, fee, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 624 total uint64, decimals uint32, defaultFrozen bool, manager, reserve, freeze, clawback, unitName, assetName, url, metadataHash string) (types.Transaction, error) { 625 tx, err := MakeAssetCreateTxn(account, fee, firstRound, lastRound, note, genesisID, genesisHash, total, decimals, defaultFrozen, manager, reserve, freeze, clawback, unitName, assetName, url, metadataHash) 626 if err != nil { 627 return types.Transaction{}, err 628 } 629 630 tx.Fee = types.MicroAlgos(fee) 631 632 if tx.Fee < MinTxnFee { 633 tx.Fee = MinTxnFee 634 } 635 636 return tx, nil 637 } 638 639 // MakeAssetConfigTxnWithFlatFee creates a tx template for changing the 640 // keys for an asset. An empty string means a zero key (which 641 // cannot be changed after becoming zero); to keep a key 642 // unchanged, you must specify that key. 643 // Deprecated: next major version will use a Params object, see package future 644 func MakeAssetConfigTxnWithFlatFee(account string, fee, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 645 index uint64, newManager, newReserve, newFreeze, newClawback string, strictEmptyAddressChecking bool) (types.Transaction, error) { 646 tx, err := MakeAssetConfigTxn(account, fee, firstRound, lastRound, note, genesisID, genesisHash, 647 index, newManager, newReserve, newFreeze, newClawback, strictEmptyAddressChecking) 648 if err != nil { 649 return types.Transaction{}, err 650 } 651 652 tx.Fee = types.MicroAlgos(fee) 653 654 if tx.Fee < MinTxnFee { 655 tx.Fee = MinTxnFee 656 } 657 return tx, nil 658 } 659 660 // MakeAssetTransferTxnWithFlatFee creates a tx for sending some asset from an asset holder to another user 661 // the recipient address must have previously issued an asset acceptance transaction for this asset 662 // - account is a checksummed, human-readable address that will send the transaction and assets 663 // - recipient is a checksummed, human-readable address what will receive the assets 664 // - closeAssetsTo is a checksummed, human-readable address that behaves as a close-to address for the asset transaction; the remaining assets not sent to recipient will be sent to closeAssetsTo. Leave blank for no close-to behavior. 665 // - amount is the number of assets to send 666 // - fee is a flat fee 667 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 668 // - lastRound is the last round this txn is valid 669 // - genesis id corresponds to the id of the network 670 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 671 // - index is the asset index 672 func MakeAssetTransferTxnWithFlatFee(account, recipient, closeAssetsTo string, amount, fee, firstRound, lastRound uint64, note []byte, 673 genesisID, genesisHash string, index uint64) (types.Transaction, error) { 674 tx, err := MakeAssetTransferTxn(account, recipient, closeAssetsTo, amount, 675 fee, firstRound, lastRound, note, genesisID, genesisHash, index) 676 if err != nil { 677 return types.Transaction{}, err 678 } 679 680 tx.Fee = types.MicroAlgos(fee) 681 682 if tx.Fee < MinTxnFee { 683 tx.Fee = MinTxnFee 684 } 685 return tx, nil 686 } 687 688 // MakeAssetAcceptanceTxnWithFlatFee creates a tx for marking an account as willing to accept an asset 689 // - account is a checksummed, human-readable address that will send the transaction and begin accepting the asset 690 // - fee is a flat fee 691 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 692 // - lastRound is the last round this txn is valid 693 // - genesis id corresponds to the id of the network 694 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 695 // - index is the asset index 696 // Deprecated: next major version will use a Params object, see package future 697 func MakeAssetAcceptanceTxnWithFlatFee(account string, fee, firstRound, lastRound uint64, note []byte, 698 genesisID, genesisHash string, index uint64) (types.Transaction, error) { 699 tx, err := MakeAssetTransferTxnWithFlatFee(account, account, "", 0, 700 fee, firstRound, lastRound, note, genesisID, genesisHash, index) 701 return tx, err 702 } 703 704 // MakeAssetRevocationTxnWithFlatFee creates a tx for revoking an asset from an account and sending it to another 705 // - account is a checksummed, human-readable address; it must be the revocation manager / clawback address from the asset's parameters 706 // - target is a checksummed, human-readable address; it is the account whose assets will be revoked 707 // - recipient is a checksummed, human-readable address; it will receive the revoked assets 708 // - fee is a flat fee 709 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 710 // - lastRound is the last round this txn is valid 711 // - note is an arbitrary byte array 712 // - genesis id corresponds to the id of the network 713 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 714 // - index is the asset index 715 // Deprecated: next major version will use a Params object, see package future 716 func MakeAssetRevocationTxnWithFlatFee(account, target, recipient string, amount, fee, firstRound, lastRound uint64, note []byte, 717 genesisID, genesisHash, creator string, index uint64) (types.Transaction, error) { 718 tx, err := MakeAssetRevocationTxn(account, target, recipient, amount, fee, firstRound, lastRound, 719 note, genesisID, genesisHash, index) 720 721 if err != nil { 722 return types.Transaction{}, err 723 } 724 725 tx.Fee = types.MicroAlgos(fee) 726 727 if tx.Fee < MinTxnFee { 728 tx.Fee = MinTxnFee 729 } 730 return tx, nil 731 } 732 733 // MakeAssetDestroyTxnWithFlatFee creates a tx template for destroying an asset, removing it from the record. 734 // All outstanding asset amount must be held by the creator, and this transaction must be issued by the asset manager. 735 // - account is a checksummed, human-readable address that will send the transaction; it also must be the asset manager 736 // - fee is a flat fee 737 // - firstRound is the first round this txn is valid (txn semantics unrelated to asset management) 738 // - lastRound is the last round this txn is valid 739 // - genesis id corresponds to the id of the network 740 // - genesis hash corresponds to the base64-encoded hash of the genesis of the network 741 // - index is the asset index 742 // Deprecated: next major version will use a Params object, see package future 743 func MakeAssetDestroyTxnWithFlatFee(account string, fee, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 744 creator string, index uint64) (types.Transaction, error) { 745 tx, err := MakeAssetConfigTxnWithFlatFee(account, fee, firstRound, lastRound, note, genesisID, genesisHash, 746 index, "", "", "", "", false) 747 return tx, err 748 } 749 750 // MakeAssetFreezeTxnWithFlatFee is as MakeAssetFreezeTxn, but taking a flat fee rather than a fee per byte. 751 // Deprecated: next major version will use a Params object, see package future 752 func MakeAssetFreezeTxnWithFlatFee(account string, fee, firstRound, lastRound uint64, note []byte, genesisID, genesisHash string, 753 creator string, assetIndex uint64, target string, newFreezeSetting bool) (types.Transaction, error) { 754 tx, err := MakeAssetFreezeTxn(account, fee, firstRound, lastRound, note, genesisID, genesisHash, 755 assetIndex, target, newFreezeSetting) 756 if err != nil { 757 return types.Transaction{}, err 758 } 759 760 tx.Fee = types.MicroAlgos(fee) 761 762 if tx.Fee < MinTxnFee { 763 tx.Fee = MinTxnFee 764 } 765 return tx, nil 766 } 767 768 // AssignGroupID computes and return list of transactions with Group field set. 769 // - txns is a list of transactions to process 770 // - account specifies a sender field of transaction to return. Set to empty string to return all of them 771 func AssignGroupID(txns []types.Transaction, account string) (result []types.Transaction, err error) { 772 gid, err := crypto.ComputeGroupID(txns) 773 if err != nil { 774 return 775 } 776 var decoded types.Address 777 if account != "" { 778 decoded, err = types.DecodeAddress(account) 779 if err != nil { 780 return 781 } 782 } 783 for _, tx := range txns { 784 if account == "" || bytes.Compare(tx.Sender[:], decoded[:]) == 0 { 785 tx.Group = gid 786 result = append(result, tx) 787 } 788 } 789 return result, nil 790 } 791 792 // EstimateSize returns the estimated length of the encoded transaction 793 func EstimateSize(txn types.Transaction) (uint64, error) { 794 return uint64(len(msgpack.Encode(txn))) + NumOfAdditionalBytesAfterSigning, nil 795 } 796 797 // byte32FromBase64 decodes the input base64 string and outputs a 798 // 32 byte array, erroring if the input is the wrong length. 799 func byte32FromBase64(in string) (out [32]byte, err error) { 800 slice, err := base64.StdEncoding.DecodeString(in) 801 if err != nil { 802 return 803 } 804 if len(slice) != 32 { 805 return out, fmt.Errorf("Input is not 32 bytes") 806 } 807 copy(out[:], slice) 808 return 809 }