From 38a2af8cd52c8be7a45d0b2db30d26b41daa1f88 Mon Sep 17 00:00:00 2001 From: catbref Date: Fri, 15 May 2020 16:22:13 +0100 Subject: [PATCH] Tidy up Assets by removing 'owner' from ISSUE_ASSET. Owner now derived from issuer's public key. Maximum asset name length reduced to 40 characters. Repository table changes. "owner" removed from test blockchain configs and "issuerPublicKey" used instead where applicable. Some getters in the form of "getIs___()" renamed to simply "is____()". --- src/main/java/org/qortal/asset/Asset.java | 21 +++++++++----- src/main/java/org/qortal/asset/Order.java | 4 +-- .../java/org/qortal/data/asset/AssetData.java | 4 +-- .../IssueAssetTransactionData.java | 22 ++++---------- src/main/java/org/qortal/payment/Payment.java | 4 +-- .../hsqldb/HSQLDBAssetRepository.java | 4 +-- .../hsqldb/HSQLDBDatabaseUpdates.java | 3 +- ...HSQLDBIssueAssetTransactionRepository.java | 25 ++++++++-------- .../org/qortal/transaction/AtTransaction.java | 2 +- .../CreateAssetOrderTransaction.java | 6 ++-- .../transaction/DeployAtTransaction.java | 4 +-- .../transaction/IssueAssetTransaction.java | 29 +++++-------------- .../IssueAssetTransactionTransformer.java | 14 +++------ .../org/qortal/test/common/AssetUtils.java | 2 +- .../IssueAssetTestTransaction.java | 3 +- .../qortal/test/group/GroupApprovalTests.java | 2 +- .../test-chain-v2-founder-rewards.json | 6 ++-- src/test/resources/test-chain-v2-minting.json | 6 ++-- .../test-chain-v2-qora-holder-extremes.json | 12 ++++---- .../resources/test-chain-v2-qora-holder.json | 12 ++++---- src/test/resources/test-chain-v2.json | 12 ++++---- 21 files changed, 85 insertions(+), 112 deletions(-) diff --git a/src/main/java/org/qortal/asset/Asset.java b/src/main/java/org/qortal/asset/Asset.java index 15135356..eadc4778 100644 --- a/src/main/java/org/qortal/asset/Asset.java +++ b/src/main/java/org/qortal/asset/Asset.java @@ -1,5 +1,6 @@ package org.qortal.asset; +import org.qortal.crypto.Crypto; import org.qortal.data.asset.AssetData; import org.qortal.data.transaction.IssueAssetTransactionData; import org.qortal.data.transaction.TransactionData; @@ -22,7 +23,7 @@ public class Asset { // Other useful constants - public static final int MAX_NAME_SIZE = 400; + public static final int MAX_NAME_SIZE = 40; public static final int MAX_DESCRIPTION_SIZE = 4000; public static final int MAX_DATA_SIZE = 400000; @@ -42,11 +43,13 @@ public class Asset { public Asset(Repository repository, IssueAssetTransactionData issueAssetTransactionData) { this.repository = repository; + String ownerAddress = Crypto.toAddress(issueAssetTransactionData.getCreatorPublicKey()); + // NOTE: transaction's reference is used to look up newly assigned assetID on creation! - this.assetData = new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), + this.assetData = new AssetData(ownerAddress, issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(), issueAssetTransactionData.getQuantity(), - issueAssetTransactionData.getIsDivisible(), issueAssetTransactionData.getData(), - issueAssetTransactionData.getIsUnspendable(), + issueAssetTransactionData.isDivisible(), issueAssetTransactionData.getData(), + issueAssetTransactionData.isUnspendable(), issueAssetTransactionData.getTxGroupId(), issueAssetTransactionData.getSignature()); } @@ -118,10 +121,11 @@ public class Asset { throw new IllegalStateException("Missing referenced transaction when orphaning UPDATE_ASSET"); switch (previousTransactionData.getType()) { - case ISSUE_ASSET: + case ISSUE_ASSET: { IssueAssetTransactionData previousIssueAssetTransactionData = (IssueAssetTransactionData) previousTransactionData; - this.assetData.setOwner(previousIssueAssetTransactionData.getOwner()); + String ownerAddress = Crypto.toAddress(previousIssueAssetTransactionData.getCreatorPublicKey()); + this.assetData.setOwner(ownerAddress); if (needDescription) { this.assetData.setDescription(previousIssueAssetTransactionData.getDescription()); @@ -133,8 +137,9 @@ public class Asset { needData = false; } break; + } - case UPDATE_ASSET: + case UPDATE_ASSET: { UpdateAssetTransactionData previousUpdateAssetTransactionData = (UpdateAssetTransactionData) previousTransactionData; this.assetData.setOwner(previousUpdateAssetTransactionData.getNewOwner()); @@ -152,7 +157,9 @@ public class Asset { // Get signature for previous transaction in chain, just in case we need it if (needDescription || needData) previousTransactionSignature = previousUpdateAssetTransactionData.getOrphanReference(); + break; + } default: throw new IllegalStateException("Invalid referenced transaction when orphaning UPDATE_ASSET"); diff --git a/src/main/java/org/qortal/asset/Order.java b/src/main/java/org/qortal/asset/Order.java index cf170266..953ff6ac 100644 --- a/src/main/java/org/qortal/asset/Order.java +++ b/src/main/java/org/qortal/asset/Order.java @@ -335,7 +335,7 @@ public class Order { continue; // Calculate amount granularity, based on price and both assets' divisibility, so that return-amount traded is a valid value (integer or to 8 d.p.) - long granularity = calculateAmountGranularity(matchingAssetData.getIsDivisible(), returnAssetData.getIsDivisible(), theirOrderData.getPrice()); + long granularity = calculateAmountGranularity(matchingAssetData.isDivisible(), returnAssetData.isDivisible(), theirOrderData.getPrice()); LOGGER.trace(() -> String.format("granularity (amount granularity): %s %s", prettyAmount(granularity), matchingAssetData.getName())); // Reduce matched amount (if need be) to fit granularity @@ -395,7 +395,7 @@ public class Order { * @throws DataException if divisibility check fails */ private void checkDivisibility(AssetData assetData, long amount, OrderData orderData) throws DataException { - if (assetData.getIsDivisible() || amount % Amounts.MULTIPLIER == 0) + if (assetData.isDivisible() || amount % Amounts.MULTIPLIER == 0) // Asset is divisible or amount has no fractional part return; diff --git a/src/main/java/org/qortal/data/asset/AssetData.java b/src/main/java/org/qortal/data/asset/AssetData.java index b98919e4..70e8afaf 100644 --- a/src/main/java/org/qortal/data/asset/AssetData.java +++ b/src/main/java/org/qortal/data/asset/AssetData.java @@ -84,7 +84,7 @@ public class AssetData { return this.quantity; } - public boolean getIsDivisible() { + public boolean isDivisible() { return this.isDivisible; } @@ -96,7 +96,7 @@ public class AssetData { this.data = data; } - public boolean getIsUnspendable() { + public boolean isUnspendable() { return this.isUnspendable; } diff --git a/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java b/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java index 071bade7..e9a932bf 100644 --- a/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/IssueAssetTransactionData.java @@ -29,9 +29,6 @@ public class IssueAssetTransactionData extends TransactionData { @Schema(description = "asset issuer's public key", example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP") private byte[] issuerPublicKey; - @Schema(description = "asset owner's address", example = "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v") - private String owner; - @Schema(description = "asset name", example = "GOLD") private String assetName; @@ -72,12 +69,11 @@ public class IssueAssetTransactionData extends TransactionData { /** From repository */ public IssueAssetTransactionData(BaseTransactionData baseTransactionData, - Long assetId, String owner, String assetName, String description, long quantity, boolean isDivisible, String data, boolean isUnspendable) { + Long assetId, String assetName, String description, long quantity, boolean isDivisible, String data, boolean isUnspendable) { super(TransactionType.ISSUE_ASSET, baseTransactionData); this.assetId = assetId; this.issuerPublicKey = baseTransactionData.creatorPublicKey; - this.owner = owner; this.assetName = assetName; this.description = description; this.quantity = quantity; @@ -87,9 +83,9 @@ public class IssueAssetTransactionData extends TransactionData { } /** From network/API */ - public IssueAssetTransactionData(BaseTransactionData baseTransactionData, String owner, String assetName, String description, + public IssueAssetTransactionData(BaseTransactionData baseTransactionData, String assetName, String description, long quantity, boolean isDivisible, String data, boolean isUnspendable) { - this(baseTransactionData, null, owner, assetName, description, quantity, isDivisible, data, isUnspendable); + this(baseTransactionData, null, assetName, description, quantity, isDivisible, data, isUnspendable); } // Getters/Setters @@ -106,14 +102,6 @@ public class IssueAssetTransactionData extends TransactionData { return this.issuerPublicKey; } - public String getOwner() { - return this.owner; - } - - public void setOwner(String owner) { - this.owner = owner; - } - public String getAssetName() { return this.assetName; } @@ -126,7 +114,7 @@ public class IssueAssetTransactionData extends TransactionData { return this.quantity; } - public boolean getIsDivisible() { + public boolean isDivisible() { return this.isDivisible; } @@ -134,7 +122,7 @@ public class IssueAssetTransactionData extends TransactionData { return this.data; } - public boolean getIsUnspendable() { + public boolean isUnspendable() { return this.isUnspendable; } diff --git a/src/main/java/org/qortal/payment/Payment.java b/src/main/java/org/qortal/payment/Payment.java index 75738f4f..cd7f1118 100644 --- a/src/main/java/org/qortal/payment/Payment.java +++ b/src/main/java/org/qortal/payment/Payment.java @@ -86,7 +86,7 @@ public class Payment { return ValidationResult.ASSET_DOES_NOT_EXIST; // Do not allow non-owner asset holders to use asset - if (assetData.getIsUnspendable() && !assetData.getOwner().equals(sender.getAddress())) + if (assetData.isUnspendable() && !assetData.getOwner().equals(sender.getAddress())) return ValidationResult.ASSET_NOT_SPENDABLE; // If we're sending to an AT then assetId must match AT's assetId @@ -94,7 +94,7 @@ public class Payment { return ValidationResult.ASSET_DOES_NOT_MATCH_AT; // Check asset amount is integer if asset is not divisible - if (!assetData.getIsDivisible() && paymentData.getAmount() % Amounts.MULTIPLIER != 0) + if (!assetData.isDivisible() && paymentData.getAmount() % Amounts.MULTIPLIER != 0) return ValidationResult.INVALID_AMOUNT; // Set or add amount into amounts-by-asset map diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java index 878bab7a..4257c6c2 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBAssetRepository.java @@ -159,8 +159,8 @@ public class HSQLDBAssetRepository implements AssetRepository { saveHelper.bind("asset_id", assetData.getAssetId()).bind("owner", assetData.getOwner()) .bind("asset_name", assetData.getName()).bind("description", assetData.getDescription()) - .bind("quantity", assetData.getQuantity()).bind("is_divisible", assetData.getIsDivisible()) - .bind("data", assetData.getData()).bind("is_unspendable", assetData.getIsUnspendable()) + .bind("quantity", assetData.getQuantity()).bind("is_divisible", assetData.isDivisible()) + .bind("data", assetData.getData()).bind("is_unspendable", assetData.isUnspendable()) .bind("creation_group_id", assetData.getCreationGroupId()).bind("reference", assetData.getReference()); try { diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index 730740cd..3d70d468 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -380,8 +380,7 @@ public class HSQLDBDatabaseUpdates { stmt.execute("CREATE INDEX AssetTradeSellOrderIndex on AssetTrades (target_order_id, traded_when)"); // Issue Asset Transactions - stmt.execute("CREATE TABLE IssueAssetTransactions (signature Signature, issuer QortalPublicKey NOT NULL, owner QortalAddress NOT NULL, " - + "asset_name AssetName NOT NULL, " + stmt.execute("CREATE TABLE IssueAssetTransactions (signature Signature, issuer QortalPublicKey NOT NULL, asset_name AssetName NOT NULL, " + "description GenericDescription NOT NULL, quantity BIGINT NOT NULL, is_divisible BOOLEAN NOT NULL, asset_id AssetID, " + "is_unspendable BOOLEAN NOT NULL, data AssetData NOT NULL DEFAULT '', " + TRANSACTION_KEYS + ")"); diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java index 6c99f7ae..217cb654 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java @@ -17,26 +17,25 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo } TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException { - String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, is_unspendable, asset_id FROM IssueAssetTransactions WHERE signature = ?"; + String sql = "SELECT asset_name, description, quantity, is_divisible, data, is_unspendable, asset_id FROM IssueAssetTransactions WHERE signature = ?"; try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) { if (resultSet == null) return null; - String owner = resultSet.getString(1); - String assetName = resultSet.getString(2); - String description = resultSet.getString(3); - long quantity = resultSet.getLong(4); - boolean isDivisible = resultSet.getBoolean(5); - String data = resultSet.getString(6); - boolean isUnspendable = resultSet.getBoolean(7); + String assetName = resultSet.getString(1); + String description = resultSet.getString(2); + long quantity = resultSet.getLong(3); + boolean isDivisible = resultSet.getBoolean(4); + String data = resultSet.getString(5); + boolean isUnspendable = resultSet.getBoolean(6); // Special null-checking for asset ID - Long assetId = resultSet.getLong(8); + Long assetId = resultSet.getLong(7); if (assetId == 0 && resultSet.wasNull()) assetId = null; - return new IssueAssetTransactionData(baseTransactionData, assetId, owner, assetName, description, quantity, isDivisible, + return new IssueAssetTransactionData(baseTransactionData, assetId, assetName, description, quantity, isDivisible, data, isUnspendable); } catch (SQLException e) { throw new DataException("Unable to fetch issue asset transaction from repository", e); @@ -50,10 +49,10 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo HSQLDBSaver saveHelper = new HSQLDBSaver("IssueAssetTransactions"); saveHelper.bind("signature", issueAssetTransactionData.getSignature()).bind("issuer", issueAssetTransactionData.getIssuerPublicKey()) - .bind("owner", issueAssetTransactionData.getOwner()).bind("asset_name", issueAssetTransactionData.getAssetName()) + .bind("asset_name", issueAssetTransactionData.getAssetName()) .bind("description", issueAssetTransactionData.getDescription()).bind("quantity", issueAssetTransactionData.getQuantity()) - .bind("is_divisible", issueAssetTransactionData.getIsDivisible()).bind("data", issueAssetTransactionData.getData()) - .bind("is_unspendable", issueAssetTransactionData.getIsUnspendable()).bind("asset_id", issueAssetTransactionData.getAssetId()); + .bind("is_divisible", issueAssetTransactionData.isDivisible()).bind("data", issueAssetTransactionData.getData()) + .bind("is_unspendable", issueAssetTransactionData.isUnspendable()).bind("asset_id", issueAssetTransactionData.getAssetId()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qortal/transaction/AtTransaction.java b/src/main/java/org/qortal/transaction/AtTransaction.java index 6e67b192..a7e72b2a 100644 --- a/src/main/java/org/qortal/transaction/AtTransaction.java +++ b/src/main/java/org/qortal/transaction/AtTransaction.java @@ -114,7 +114,7 @@ public class AtTransaction extends Transaction { return ValidationResult.ASSET_DOES_NOT_EXIST; // Check asset amount is integer if asset is not divisible - if (!assetData.getIsDivisible() && amount % Amounts.MULTIPLIER != 0) + if (!assetData.isDivisible() && amount % Amounts.MULTIPLIER != 0) return ValidationResult.INVALID_AMOUNT; Account sender = getATAccount(); diff --git a/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java b/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java index 3635c797..36cccf42 100644 --- a/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java +++ b/src/main/java/org/qortal/transaction/CreateAssetOrderTransaction.java @@ -76,7 +76,7 @@ public class CreateAssetOrderTransaction extends Transaction { return ValidationResult.ASSET_DOES_NOT_EXIST; // Unspendable assets are not tradable - if (haveAssetData.getIsUnspendable() || wantAssetData.getIsUnspendable()) + if (haveAssetData.isUnspendable() || wantAssetData.isUnspendable()) return ValidationResult.ASSET_NOT_SPENDABLE; Account creator = getCreator(); @@ -109,11 +109,11 @@ public class CreateAssetOrderTransaction extends Transaction { } // Check amount is integer if amount's asset is not divisible - if (!haveAssetData.getIsDivisible() && committedCost.mod(Amounts.MULTIPLIER_BI).signum() != 0) + if (!haveAssetData.isDivisible() && committedCost.mod(Amounts.MULTIPLIER_BI).signum() != 0) return ValidationResult.INVALID_AMOUNT; // Check total return from fulfilled order would be integer if return's asset is not divisible - if (!wantAssetData.getIsDivisible() && maxOtherAmount.mod(Amounts.MULTIPLIER_BI).signum() != 0) + if (!wantAssetData.isDivisible() && maxOtherAmount.mod(Amounts.MULTIPLIER_BI).signum() != 0) return ValidationResult.INVALID_RETURN; // Check order creator has enough asset balance AFTER removing fee, in case asset is QORT diff --git a/src/main/java/org/qortal/transaction/DeployAtTransaction.java b/src/main/java/org/qortal/transaction/DeployAtTransaction.java index 9986819c..7c48bc95 100644 --- a/src/main/java/org/qortal/transaction/DeployAtTransaction.java +++ b/src/main/java/org/qortal/transaction/DeployAtTransaction.java @@ -113,11 +113,11 @@ public class DeployAtTransaction extends Transaction { return ValidationResult.ASSET_DOES_NOT_EXIST; // Unspendable assets are not valid - if (assetData.getIsUnspendable()) + if (assetData.isUnspendable()) return ValidationResult.ASSET_NOT_SPENDABLE; // Check asset amount is integer if asset is not divisible - if (!assetData.getIsDivisible() && this.deployATTransactionData.getAmount() % Amounts.MULTIPLIER != 0) + if (!assetData.isDivisible() && this.deployATTransactionData.getAmount() % Amounts.MULTIPLIER != 0) return ValidationResult.INVALID_AMOUNT; Account creator = this.getCreator(); diff --git a/src/main/java/org/qortal/transaction/IssueAssetTransaction.java b/src/main/java/org/qortal/transaction/IssueAssetTransaction.java index 3c27c7a7..e4c9cf63 100644 --- a/src/main/java/org/qortal/transaction/IssueAssetTransaction.java +++ b/src/main/java/org/qortal/transaction/IssueAssetTransaction.java @@ -5,7 +5,6 @@ import java.util.List; import org.qortal.account.Account; import org.qortal.asset.Asset; -import org.qortal.crypto.Crypto; import org.qortal.data.transaction.IssueAssetTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; @@ -19,7 +18,6 @@ public class IssueAssetTransaction extends Transaction { // Properties private IssueAssetTransactionData issueAssetTransactionData; - private Account ownerAccount = null; // Constructors @@ -33,7 +31,7 @@ public class IssueAssetTransaction extends Transaction { @Override public List getRecipientAddresses() throws DataException { - return Collections.singletonList(this.issueAssetTransactionData.getOwner()); + return Collections.emptyList(); } // Navigation @@ -42,21 +40,10 @@ public class IssueAssetTransaction extends Transaction { return this.getCreator(); } - public Account getOwner() { - if (this.ownerAccount == null) - this.ownerAccount = new Account(this.repository, this.issueAssetTransactionData.getOwner()); - - return this.ownerAccount; - } - // Processing @Override public ValidationResult isValid() throws DataException { - // Check owner address is valid - if (!Crypto.isValidAddress(this.issueAssetTransactionData.getOwner())) - return ValidationResult.INVALID_ADDRESS; - // Check name size bounds int assetNameLength = Utf8.encodedLength(this.issueAssetTransactionData.getAssetName()); if (assetNameLength < 1 || assetNameLength > Asset.MAX_NAME_SIZE) @@ -78,7 +65,7 @@ public class IssueAssetTransaction extends Transaction { return ValidationResult.INVALID_QUANTITY; // Check quantity versus indivisibility - if (!this.issueAssetTransactionData.getIsDivisible() && this.issueAssetTransactionData.getQuantity() % Amounts.MULTIPLIER != 0) + if (!this.issueAssetTransactionData.isDivisible() && this.issueAssetTransactionData.getQuantity() % Amounts.MULTIPLIER != 0) return ValidationResult.INVALID_QUANTITY; Account issuer = getIssuer(); @@ -105,9 +92,9 @@ public class IssueAssetTransaction extends Transaction { Asset asset = new Asset(this.repository, this.issueAssetTransactionData); asset.issue(); - // Add asset to owner - Account owner = getOwner(); - owner.setConfirmedBalance(asset.getAssetData().getAssetId(), this.issueAssetTransactionData.getQuantity()); + // Add asset to issuer + Account issuer = this.getIssuer(); + issuer.setConfirmedBalance(asset.getAssetData().getAssetId(), this.issueAssetTransactionData.getQuantity()); // Note newly assigned asset ID in our transaction record this.issueAssetTransactionData.setAssetId(asset.getAssetData().getAssetId()); @@ -118,9 +105,9 @@ public class IssueAssetTransaction extends Transaction { @Override public void orphan() throws DataException { - // Remove asset from owner - Account owner = getOwner(); - owner.deleteBalance(this.issueAssetTransactionData.getAssetId()); + // Remove asset from issuer + Account issuer = this.getIssuer(); + issuer.deleteBalance(this.issueAssetTransactionData.getAssetId()); // Deissue asset Asset asset = new Asset(this.repository, this.issueAssetTransactionData.getAssetId()); diff --git a/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java index c420dbef..59cbd6bc 100644 --- a/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/IssueAssetTransactionTransformer.java @@ -18,7 +18,6 @@ import com.google.common.primitives.Longs; public class IssueAssetTransactionTransformer extends TransactionTransformer { // Property lengths - private static final int OWNER_LENGTH = ADDRESS_LENGTH; private static final int NAME_SIZE_LENGTH = INT_LENGTH; private static final int DESCRIPTION_SIZE_LENGTH = INT_LENGTH; private static final int QUANTITY_LENGTH = AMOUNT_LENGTH; @@ -26,7 +25,7 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { private static final int DATA_SIZE_LENGTH = INT_LENGTH; private static final int IS_UNSPENDABLE_LENGTH = BOOLEAN_LENGTH; - private static final int EXTRAS_LENGTH = OWNER_LENGTH + NAME_SIZE_LENGTH + DESCRIPTION_SIZE_LENGTH + QUANTITY_LENGTH + private static final int EXTRAS_LENGTH = NAME_SIZE_LENGTH + DESCRIPTION_SIZE_LENGTH + QUANTITY_LENGTH + IS_DIVISIBLE_LENGTH + DATA_SIZE_LENGTH + IS_UNSPENDABLE_LENGTH; protected static final TransactionLayout layout; @@ -38,7 +37,6 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { layout.add("transaction's groupID", TransformationType.INT); layout.add("reference", TransformationType.SIGNATURE); layout.add("asset issuer's public key", TransformationType.PUBLIC_KEY); - layout.add("asset owner", TransformationType.ADDRESS); layout.add("asset name length", TransformationType.INT); layout.add("asset name", TransformationType.STRING); layout.add("asset description length", TransformationType.INT); @@ -62,8 +60,6 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { byte[] issuerPublicKey = Serialization.deserializePublicKey(byteBuffer); - String owner = Serialization.deserializeAddress(byteBuffer); - String assetName = Serialization.deserializeSizedString(byteBuffer, Asset.MAX_NAME_SIZE); String description = Serialization.deserializeSizedString(byteBuffer, Asset.MAX_DESCRIPTION_SIZE); @@ -83,7 +79,7 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, issuerPublicKey, fee, signature); - return new IssueAssetTransactionData(baseTransactionData, owner, assetName, description, quantity, isDivisible, data, isUnspendable); + return new IssueAssetTransactionData(baseTransactionData, assetName, description, quantity, isDivisible, data, isUnspendable); } public static int getDataLength(TransactionData transactionData) throws TransformationException { @@ -103,18 +99,16 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { transformCommonBytes(transactionData, bytes); - Serialization.serializeAddress(bytes, issueAssetTransactionData.getOwner()); - Serialization.serializeSizedString(bytes, issueAssetTransactionData.getAssetName()); Serialization.serializeSizedString(bytes, issueAssetTransactionData.getDescription()); bytes.write(Longs.toByteArray(issueAssetTransactionData.getQuantity())); - bytes.write((byte) (issueAssetTransactionData.getIsDivisible() ? 1 : 0)); + bytes.write((byte) (issueAssetTransactionData.isDivisible() ? 1 : 0)); Serialization.serializeSizedString(bytes, issueAssetTransactionData.getData()); - bytes.write((byte) (issueAssetTransactionData.getIsUnspendable() ? 1 : 0)); + bytes.write((byte) (issueAssetTransactionData.isUnspendable() ? 1 : 0)); bytes.write(Longs.toByteArray(issueAssetTransactionData.getFee())); diff --git a/src/test/java/org/qortal/test/common/AssetUtils.java b/src/test/java/org/qortal/test/common/AssetUtils.java index 92918169..7118a79d 100644 --- a/src/test/java/org/qortal/test/common/AssetUtils.java +++ b/src/test/java/org/qortal/test/common/AssetUtils.java @@ -41,7 +41,7 @@ public class AssetUtils { long timestamp = repository.getTransactionRepository().fromSignature(reference).getTimestamp() + 1; BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, AssetUtils.txGroupId, reference, account.getPublicKey(), AssetUtils.fee, null); - TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, account.getAddress(), assetName, "desc", quantity, isDivisible, "{}", false); + TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, assetName, "desc", quantity, isDivisible, "{}", false); TransactionUtils.signAndMint(repository, transactionData, account); diff --git a/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java index 659f1878..fb04d2cf 100644 --- a/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/IssueAssetTestTransaction.java @@ -14,7 +14,6 @@ public class IssueAssetTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { Random random = new Random(); - String owner = account.getAddress(); String assetName = "test-asset-" + random.nextInt(1_000_000); String description = "random test asset"; final long quantity = 1_000_000L; @@ -22,7 +21,7 @@ public class IssueAssetTestTransaction extends TestTransaction { String data = AssetUtils.randomData(); final boolean isUnspendable = false; - return new IssueAssetTransactionData(generateBase(account), owner, assetName, description, quantity, isDivisible, data, isUnspendable); + return new IssueAssetTransactionData(generateBase(account), assetName, description, quantity, isDivisible, data, isUnspendable); } } diff --git a/src/test/java/org/qortal/test/group/GroupApprovalTests.java b/src/test/java/org/qortal/test/group/GroupApprovalTests.java index 34d34c22..b8b870f5 100644 --- a/src/test/java/org/qortal/test/group/GroupApprovalTests.java +++ b/src/test/java/org/qortal/test/group/GroupApprovalTests.java @@ -434,7 +434,7 @@ public class GroupApprovalTests extends Common { long timestamp = repository.getTransactionRepository().fromSignature(reference).getTimestamp() + 1; BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, account.getPublicKey(), fee, null); - TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, account.getAddress(), "test asset", "test asset desc", 1000L, true, "{}", false); + TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, "test asset", "test asset desc", 1000L, true, "{}", false); return Transaction.fromData(repository, transactionData); } diff --git a/src/test/resources/test-chain-v2-founder-rewards.json b/src/test/resources/test-chain-v2-founder-rewards.json index 18adf859..4ad21f35 100644 --- a/src/test/resources/test-chain-v2-founder-rewards.json +++ b/src/test/resources/test-chain-v2-founder-rewards.json @@ -50,9 +50,9 @@ "version": 4, "timestamp": 0, "transactions": [ - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, { "type": "ACCOUNT_FLAGS", "target": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "andMask": -1, "orMask": 1, "xorMask": 0 }, { "type": "REWARD_SHARE", "minterPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "rewardSharePublicKey": "7PpfnvLSG7y4HPh8hE7KoqAjLCkv7Ui6xw4mKAkbZtox", "sharePercent": 100 }, diff --git a/src/test/resources/test-chain-v2-minting.json b/src/test/resources/test-chain-v2-minting.json index 90b5a306..02b31ef9 100644 --- a/src/test/resources/test-chain-v2-minting.json +++ b/src/test/resources/test-chain-v2-minting.json @@ -50,9 +50,9 @@ "version": 4, "timestamp": 0, "transactions": [ - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, { "type": "GENESIS", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "amount": "1000000000" }, { "type": "GENESIS", "recipient": "QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK", "amount": "1000000" }, diff --git a/src/test/resources/test-chain-v2-qora-holder-extremes.json b/src/test/resources/test-chain-v2-qora-holder-extremes.json index 0321ef6b..2bd65c5f 100644 --- a/src/test/resources/test-chain-v2-qora-holder-extremes.json +++ b/src/test/resources/test-chain-v2-qora-holder-extremes.json @@ -50,9 +50,9 @@ "version": 4, "timestamp": 0, "transactions": [ - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, { "type": "GENESIS", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "amount": "1000000000" }, { "type": "GENESIS", "recipient": "QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK", "amount": "1000000" }, @@ -64,9 +64,9 @@ { "type": "CREATE_GROUP", "creatorPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "groupName": "dev-group", "description": "developer group", "isOpen": false, "approvalThreshold": "PCT100", "minimumBlockDelay": 0, "maximumBlockDelay": 1440 }, - { "type": "ISSUE_ASSET", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "assetName": "TEST", "description": "test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK", "assetName": "OTHER", "description": "other test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "assetName": "GOLD", "description": "gold test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "assetName": "TEST", "description": "test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "C6wuddsBV3HzRrXUtezE7P5MoRXp5m3mEDokRDGZB6ry", "assetName": "OTHER", "description": "other test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "assetName": "GOLD", "description": "gold test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, { "type": "ACCOUNT_FLAGS", "target": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "andMask": -1, "orMask": 1, "xorMask": 0 }, { "type": "REWARD_SHARE", "minterPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "rewardSharePublicKey": "7PpfnvLSG7y4HPh8hE7KoqAjLCkv7Ui6xw4mKAkbZtox", "sharePercent": 100 }, diff --git a/src/test/resources/test-chain-v2-qora-holder.json b/src/test/resources/test-chain-v2-qora-holder.json index 59503f91..63186eb9 100644 --- a/src/test/resources/test-chain-v2-qora-holder.json +++ b/src/test/resources/test-chain-v2-qora-holder.json @@ -50,9 +50,9 @@ "version": 4, "timestamp": 0, "transactions": [ - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, { "type": "GENESIS", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "amount": "1000000000" }, { "type": "GENESIS", "recipient": "QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK", "amount": "1000000" }, @@ -64,9 +64,9 @@ { "type": "CREATE_GROUP", "creatorPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "groupName": "dev-group", "description": "developer group", "isOpen": false, "approvalThreshold": "PCT100", "minimumBlockDelay": 0, "maximumBlockDelay": 1440 }, - { "type": "ISSUE_ASSET", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "assetName": "TEST", "description": "test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK", "assetName": "OTHER", "description": "other test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "assetName": "GOLD", "description": "gold test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "assetName": "TEST", "description": "test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "C6wuddsBV3HzRrXUtezE7P5MoRXp5m3mEDokRDGZB6ry", "assetName": "OTHER", "description": "other test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "assetName": "GOLD", "description": "gold test asset", "data": "", "quantity": 1000000, "isDivisible": true, "fee": 0 }, { "type": "ACCOUNT_FLAGS", "target": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "andMask": -1, "orMask": 1, "xorMask": 0 }, { "type": "REWARD_SHARE", "minterPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "rewardSharePublicKey": "7PpfnvLSG7y4HPh8hE7KoqAjLCkv7Ui6xw4mKAkbZtox", "sharePercent": 100 }, diff --git a/src/test/resources/test-chain-v2.json b/src/test/resources/test-chain-v2.json index bb5d1afd..6ab9002b 100644 --- a/src/test/resources/test-chain-v2.json +++ b/src/test/resources/test-chain-v2.json @@ -50,9 +50,9 @@ "version": 4, "timestamp": 0, "transactions": [ - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, - { "type": "ISSUE_ASSET", "owner": "QdSnUy6sUiEnaN87dWmE92g1uQjrvPgrWG", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT", "description": "QORT native coin", "data": "", "quantity": 0, "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "assetName": "Legacy-QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, + { "type": "ISSUE_ASSET", "assetName": "QORT-from-QORA", "description": "QORT gained from holding legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, { "type": "GENESIS", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "amount": "1000000000" }, { "type": "GENESIS", "recipient": "QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK", "amount": "1000000" }, @@ -61,9 +61,9 @@ { "type": "CREATE_GROUP", "creatorPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "groupName": "dev-group", "description": "developer group", "isOpen": false, "approvalThreshold": "PCT100", "minimumBlockDelay": 0, "maximumBlockDelay": 1440 }, - { "type": "ISSUE_ASSET", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "assetName": "TEST", "description": "test asset", "data": "", "quantity": "1000000", "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK", "assetName": "OTHER", "description": "other test asset", "data": "", "quantity": "1000000", "isDivisible": true, "fee": 0 }, - { "type": "ISSUE_ASSET", "owner": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "assetName": "GOLD", "description": "gold test asset", "data": "", "quantity": "1000000", "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "assetName": "TEST", "description": "test asset", "data": "", "quantity": "1000000", "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "C6wuddsBV3HzRrXUtezE7P5MoRXp5m3mEDokRDGZB6ry", "assetName": "OTHER", "description": "other test asset", "data": "", "quantity": "1000000", "isDivisible": true, "fee": 0 }, + { "type": "ISSUE_ASSET", "issuerPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "assetName": "GOLD", "description": "gold test asset", "data": "", "quantity": "1000000", "isDivisible": true, "fee": 0 }, { "type": "ACCOUNT_FLAGS", "target": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "andMask": -1, "orMask": 1, "xorMask": 0 }, { "type": "REWARD_SHARE", "minterPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "rewardSharePublicKey": "7PpfnvLSG7y4HPh8hE7KoqAjLCkv7Ui6xw4mKAkbZtox", "sharePercent": "100" },