forked from Qortal/qortal
Fixed old Qora v1 "GenesisAccount" by replacing with NullAccount
NullAccount has 'empty' public key (32 bytes of zeros) compared with GenesisAccount's vague sometimes 8 bytes, sometimes 32 bytes public key. NullAccount has static public key and address, plus overridden methods to speed up pointless calls like verify(). Genesis Block also tidied up, dropping old Qora v1 compatibility and using proper block signature and public key to generate minter's block signature. Genesis Block transaction processing also simplified, with no need to access repository to handle fake references, due to new last-reference code (which will need to be merged). Dropped support for old, broken RMD160 code.
This commit is contained in:
parent
2602bb01e1
commit
9e2663b11b
@ -3,6 +3,9 @@ package org.qortal.account;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.qortal.block.BlockChain;
|
||||
@ -15,6 +18,7 @@ import org.qortal.repository.Repository;
|
||||
import org.qortal.transaction.Transaction;
|
||||
import org.qortal.utils.Base58;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.NONE) // Stops JAX-RS errors when unmarshalling blockchain config
|
||||
public class Account {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(Account.class);
|
||||
|
@ -1,13 +0,0 @@
|
||||
package org.qortal.account;
|
||||
|
||||
import org.qortal.repository.Repository;
|
||||
|
||||
public final class GenesisAccount extends PublicKeyAccount {
|
||||
|
||||
public static final byte[] PUBLIC_KEY = new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
public GenesisAccount(Repository repository) {
|
||||
super(repository, PUBLIC_KEY);
|
||||
}
|
||||
|
||||
}
|
24
src/main/java/org/qortal/account/NullAccount.java
Normal file
24
src/main/java/org/qortal/account/NullAccount.java
Normal file
@ -0,0 +1,24 @@
|
||||
package org.qortal.account;
|
||||
|
||||
import org.qortal.crypto.Crypto;
|
||||
import org.qortal.repository.Repository;
|
||||
|
||||
public final class NullAccount extends PublicKeyAccount {
|
||||
|
||||
public static final byte[] PUBLIC_KEY = new byte[32];
|
||||
public static final String ADDRESS = Crypto.toAddress(PUBLIC_KEY);
|
||||
|
||||
public NullAccount(Repository repository) {
|
||||
super(repository, PUBLIC_KEY, ADDRESS);
|
||||
}
|
||||
|
||||
protected NullAccount() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(byte[] signature, byte[] message) {
|
||||
// Can't sign, hence can't verify.
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,18 @@ public class PublicKeyAccount extends Account {
|
||||
this.publicKey = edPublicKeyParams.getEncoded();
|
||||
}
|
||||
|
||||
protected PublicKeyAccount(Repository repository, byte[] publicKey, String address) {
|
||||
super(repository, address);
|
||||
|
||||
this.publicKey = publicKey;
|
||||
this.edPublicKeyParams = null;
|
||||
}
|
||||
|
||||
protected PublicKeyAccount() {
|
||||
this.publicKey = null;
|
||||
this.edPublicKeyParams = null;
|
||||
}
|
||||
|
||||
public byte[] getPublicKey() {
|
||||
return this.publicKey;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import org.ciyam.at.MachineState;
|
||||
import org.ciyam.at.OpCode;
|
||||
import org.ciyam.at.Timestamp;
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.account.PublicKeyAccount;
|
||||
import org.qortal.asset.Asset;
|
||||
import org.qortal.crypto.Crypto;
|
||||
@ -270,7 +270,7 @@ public class QortalATAPI extends API {
|
||||
byte[] reference = this.getLastReference();
|
||||
BigDecimal amount = BigDecimal.valueOf(unscaledAmount, 8);
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
||||
recipient.getAddress(), amount, this.atData.getAssetId(), new byte[0]);
|
||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||
@ -289,7 +289,7 @@ public class QortalATAPI extends API {
|
||||
long timestamp = this.getNextTransactionTimestamp();
|
||||
byte[] reference = this.getLastReference();
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
||||
recipient.getAddress(), BigDecimal.ZERO, this.atData.getAssetId(), message);
|
||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||
@ -316,7 +316,7 @@ public class QortalATAPI extends API {
|
||||
byte[] reference = this.getLastReference();
|
||||
BigDecimal amount = BigDecimal.valueOf(finalBalance, 8);
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
||||
creator.getAddress(), amount, this.atData.getAssetId(), new byte[0]);
|
||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||
|
@ -7,27 +7,21 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.PublicKeyAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.crypto.Crypto;
|
||||
import org.qortal.data.asset.AssetData;
|
||||
import org.qortal.data.block.BlockData;
|
||||
import org.qortal.data.transaction.IssueAssetTransactionData;
|
||||
import org.qortal.data.transaction.TransactionData;
|
||||
import org.qortal.group.Group;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.Repository;
|
||||
import org.qortal.transaction.Transaction;
|
||||
import org.qortal.transaction.Transaction.ApprovalStatus;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
import org.qortal.transform.TransformationException;
|
||||
import org.qortal.transform.transaction.TransactionTransformer;
|
||||
|
||||
@ -39,9 +33,8 @@ public class GenesisBlock extends Block {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(GenesisBlock.class);
|
||||
|
||||
private static final byte[] GENESIS_REFERENCE = new byte[] {
|
||||
1, 1, 1, 1, 1, 1, 1, 1
|
||||
}; // NOTE: Neither 64 nor 128 bytes!
|
||||
private static final byte[] GENESIS_BLOCK_REFERENCE = new byte[128];
|
||||
private static final byte[] GENESIS_TRANSACTION_REFERENCE = new byte[64];
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public static class GenesisInfo {
|
||||
@ -96,37 +89,16 @@ public class GenesisBlock extends Block {
|
||||
transactionData.setFee(BigDecimal.ZERO.setScale(8));
|
||||
|
||||
if (transactionData.getCreatorPublicKey() == null)
|
||||
transactionData.setCreatorPublicKey(GenesisAccount.PUBLIC_KEY);
|
||||
transactionData.setCreatorPublicKey(NullAccount.PUBLIC_KEY);
|
||||
|
||||
if (transactionData.getTimestamp() == 0)
|
||||
transactionData.setTimestamp(info.timestamp);
|
||||
});
|
||||
|
||||
// For version 1, extract any ISSUE_ASSET transactions into initialAssets and only allow GENESIS transactions
|
||||
if (info.version == 1) {
|
||||
List<TransactionData> issueAssetTransactions = transactionsData.stream()
|
||||
.filter(transactionData -> transactionData.getType() == TransactionType.ISSUE_ASSET).collect(Collectors.toList());
|
||||
transactionsData.removeAll(issueAssetTransactions);
|
||||
|
||||
// There should be only GENESIS transactions left;
|
||||
if (transactionsData.stream().anyMatch(transactionData -> transactionData.getType() != TransactionType.GENESIS)) {
|
||||
LOGGER.error("Version 1 genesis block only allowed to contain GENESIS transctions (after issue-asset processing)");
|
||||
throw new RuntimeException("Version 1 genesis block only allowed to contain GENESIS transctions (after issue-asset processing)");
|
||||
}
|
||||
|
||||
// Convert ISSUE_ASSET transactions into initial assets
|
||||
initialAssets = issueAssetTransactions.stream().map(transactionData -> {
|
||||
IssueAssetTransactionData issueAssetTransactionData = (IssueAssetTransactionData) transactionData;
|
||||
|
||||
return new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(),
|
||||
issueAssetTransactionData.getQuantity(), issueAssetTransactionData.getIsDivisible(), "", false, Group.NO_GROUP, issueAssetTransactionData.getReference());
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
byte[] reference = GENESIS_REFERENCE;
|
||||
byte[] reference = GENESIS_BLOCK_REFERENCE;
|
||||
int transactionCount = transactionsData.size();
|
||||
BigDecimal totalFees = BigDecimal.ZERO.setScale(8);
|
||||
byte[] minterPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
byte[] minterPublicKey = NullAccount.PUBLIC_KEY;
|
||||
byte[] bytesForSignature = getBytesForMinterSignature(info.timestamp, reference, minterPublicKey);
|
||||
byte[] minterSignature = calcGenesisMinterSignature(bytesForSignature);
|
||||
byte[] transactionsSignature = calcGenesisTransactionsSignature();
|
||||
@ -212,24 +184,16 @@ public class GenesisBlock extends Block {
|
||||
try {
|
||||
// Passing expected size to ByteArrayOutputStream avoids reallocation when adding more bytes than default 32.
|
||||
// See below for explanation of some of the values used to calculated expected size.
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream(8 + 64 + 8 + 32);
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream(8 + 128 + 32);
|
||||
|
||||
/*
|
||||
* NOTE: Historic code had genesis block using Longs.toByteArray(version) compared to standard block's Ints.toByteArray. The subsequent
|
||||
* Bytes.ensureCapacity(versionBytes, 0, 4) did not truncate versionBytes back to 4 bytes either. This means 8 bytes were used even though
|
||||
* VERSION_LENGTH is set to 4. Correcting this historic bug will break genesis block signatures!
|
||||
*/
|
||||
// For Qortal, we use genesis timestamp instead
|
||||
// Genesis block timestamp
|
||||
bytes.write(Longs.toByteArray(timestamp));
|
||||
|
||||
/*
|
||||
* NOTE: Historic code had the reference expanded to only 64 bytes whereas standard block references are 128 bytes. Correcting this historic bug
|
||||
* will break genesis block signatures!
|
||||
*/
|
||||
bytes.write(Bytes.ensureCapacity(reference, 64, 0));
|
||||
// Block's reference
|
||||
bytes.write(reference);
|
||||
|
||||
// NOTE: Genesis account's public key is only 8 bytes, not the usual 32, so we have to pad.
|
||||
bytes.write(Bytes.ensureCapacity(minterPublicKey, 32, 0));
|
||||
// Minting account's public key (typically NullAccount)
|
||||
bytes.write(minterPublicKey);
|
||||
|
||||
return bytes.toByteArray();
|
||||
} catch (IOException e) {
|
||||
@ -295,26 +259,18 @@ public class GenesisBlock extends Block {
|
||||
public void process() throws DataException {
|
||||
LOGGER.info(String.format("Using genesis block timestamp of %d", this.blockData.getTimestamp()));
|
||||
|
||||
// If we're a version 1 genesis block, create assets now
|
||||
if (this.blockData.getVersion() == 1)
|
||||
for (AssetData assetData : initialAssets)
|
||||
repository.getAssetRepository().save(assetData);
|
||||
|
||||
/*
|
||||
* Some transactions will be missing references and signatures,
|
||||
* so we generate them by trial-processing transactions and using
|
||||
* account's last-reference to fill in the gaps for reference,
|
||||
* so we generate them by using <tt>GENESIS_TRANSACTION_REFERENCE</tt>
|
||||
* and a duplicated SHA256 digest for signature
|
||||
*/
|
||||
this.repository.setSavepoint();
|
||||
try {
|
||||
for (Transaction transaction : this.getTransactions()) {
|
||||
TransactionData transactionData = transaction.getTransactionData();
|
||||
Account creator = new PublicKeyAccount(this.repository, transactionData.getCreatorPublicKey());
|
||||
|
||||
// Missing reference?
|
||||
if (transactionData.getReference() == null)
|
||||
transactionData.setReference(creator.getLastReference());
|
||||
transactionData.setReference(GENESIS_TRANSACTION_REFERENCE);
|
||||
|
||||
// Missing signature?
|
||||
if (transactionData.getSignature() == null) {
|
||||
@ -324,18 +280,11 @@ public class GenesisBlock extends Block {
|
||||
transactionData.setSignature(signature);
|
||||
}
|
||||
|
||||
// Missing approval status (not used in V1)
|
||||
// Approval status
|
||||
transactionData.setApprovalStatus(ApprovalStatus.NOT_REQUIRED);
|
||||
|
||||
// Ask transaction to update references, etc.
|
||||
transaction.processReferencesAndFees();
|
||||
|
||||
creator.setLastReference(transactionData.getSignature());
|
||||
}
|
||||
} catch (TransformationException e) {
|
||||
throw new RuntimeException("Can't process genesis block transaction", e);
|
||||
} finally {
|
||||
this.repository.rollbackToSavepoint();
|
||||
}
|
||||
|
||||
// Save transactions into repository ready for processing
|
||||
|
@ -6,7 +6,7 @@ import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@ -31,14 +31,14 @@ public class ATTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||
}
|
||||
|
||||
/** From repository */
|
||||
public ATTransactionData(BaseTransactionData baseTransactionData, String atAddress, String recipient, BigDecimal amount, Long assetId, byte[] message) {
|
||||
super(TransactionType.AT, baseTransactionData);
|
||||
|
||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||
this.atAddress = atAddress;
|
||||
this.recipient = recipient;
|
||||
this.amount = amount;
|
||||
|
@ -6,7 +6,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.block.GenesisBlock;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
|
||||
@ -36,10 +36,10 @@ public class AccountFlagsTransactionData extends TransactionData {
|
||||
/*
|
||||
* If we're being constructed as part of the genesis block info inside blockchain config
|
||||
* and no specific creator's public key is supplied
|
||||
* then use genesis account's public key.
|
||||
* then use null account's public key.
|
||||
*/
|
||||
if (parent instanceof GenesisBlock.GenesisInfo && this.creatorPublicKey == null)
|
||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||
}
|
||||
|
||||
/** From repository */
|
||||
|
@ -6,7 +6,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.block.GenesisBlock;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
|
||||
@ -33,10 +33,10 @@ public class AccountLevelTransactionData extends TransactionData {
|
||||
/*
|
||||
* If we're being constructed as part of the genesis block info inside blockchain config
|
||||
* and no specific creator's public key is supplied
|
||||
* then use genesis account's public key.
|
||||
* then use null account's public key.
|
||||
*/
|
||||
if (parent instanceof GenesisBlock.GenesisInfo && this.creatorPublicKey == null)
|
||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||
}
|
||||
|
||||
/** From repository, network/API */
|
||||
|
@ -34,10 +34,8 @@ public class GenesisTransactionData extends TransactionData {
|
||||
super(TransactionType.GENESIS);
|
||||
}
|
||||
|
||||
/** From repository (V2) */
|
||||
/** From repository */
|
||||
public GenesisTransactionData(BaseTransactionData baseTransactionData, String recipient, BigDecimal amount, long assetId) {
|
||||
// No groupID, null reference, zero fee, no approval required, height always 1
|
||||
// super(TransactionType.GENESIS, timestamp, Group.NO_GROUP, null, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, ApprovalStatus.NOT_REQUIRED, 1, signature);
|
||||
super(TransactionType.GENESIS, baseTransactionData);
|
||||
|
||||
this.recipient = recipient;
|
||||
@ -45,7 +43,7 @@ public class GenesisTransactionData extends TransactionData {
|
||||
this.assetId = assetId;
|
||||
}
|
||||
|
||||
/** From repository (V1, where asset locked to QORT) */
|
||||
/** From repository (where asset locked to QORT) */
|
||||
public GenesisTransactionData(BaseTransactionData baseTransactionData, String recipient, BigDecimal amount) {
|
||||
this(baseTransactionData, recipient, amount, Asset.QORT);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.block.GenesisBlock;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
|
||||
@ -51,10 +51,10 @@ public class IssueAssetTransactionData extends TransactionData {
|
||||
/*
|
||||
* If we're being constructed as part of the genesis block info inside blockchain config
|
||||
* and no specific issuer's public key is supplied
|
||||
* then use genesis account's public key.
|
||||
* then use null account's public key.
|
||||
*/
|
||||
if (parent instanceof GenesisBlock.GenesisInfo && this.issuerPublicKey == null)
|
||||
this.issuerPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
this.issuerPublicKey = NullAccount.PUBLIC_KEY;
|
||||
|
||||
this.creatorPublicKey = this.issuerPublicKey;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.asset.Asset;
|
||||
import org.qortal.data.transaction.AccountFlagsTransactionData;
|
||||
import org.qortal.data.transaction.TransactionData;
|
||||
@ -68,8 +68,8 @@ public class AccountFlagsTransaction extends Transaction {
|
||||
public ValidationResult isValid() throws DataException {
|
||||
Account creator = getCreator();
|
||||
|
||||
// Only genesis account can modify flags
|
||||
if (!creator.getAddress().equals(new GenesisAccount(repository).getAddress()))
|
||||
// Only null account can modify flags
|
||||
if (!creator.getAddress().equals(NullAccount.ADDRESS))
|
||||
return ValidationResult.NO_FLAG_PERMISSION;
|
||||
|
||||
// Check fee is zero or positive
|
||||
|
@ -5,7 +5,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.asset.Asset;
|
||||
import org.qortal.block.BlockChain;
|
||||
import org.qortal.data.transaction.AccountLevelTransactionData;
|
||||
@ -70,7 +70,7 @@ public class AccountLevelTransaction extends Transaction {
|
||||
Account creator = getCreator();
|
||||
|
||||
// Only genesis account can modify level
|
||||
if (!creator.getAddress().equals(new GenesisAccount(repository).getAddress()))
|
||||
if (!creator.getAddress().equals(new NullAccount(repository).getAddress()))
|
||||
return ValidationResult.NO_FLAG_PERMISSION;
|
||||
|
||||
// Check fee is zero or positive
|
||||
|
@ -5,7 +5,7 @@ import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.qortal.account.GenesisAccount;
|
||||
import org.qortal.account.NullAccount;
|
||||
import org.qortal.data.transaction.BaseTransactionData;
|
||||
import org.qortal.data.transaction.GenesisTransactionData;
|
||||
import org.qortal.data.transaction.TransactionData;
|
||||
@ -49,7 +49,7 @@ public class GenesisTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
long assetId = byteBuffer.getLong();
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, null, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, null, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||
|
||||
return new GenesisTransactionData(baseTransactionData, recipient, amount, assetId);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user