mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Work towards Claim.
This commit is contained in:
@@ -108,35 +108,29 @@ void Application::run()
|
||||
|
||||
// New stuff.
|
||||
NewcoinAddress rootSeedMaster;
|
||||
NewcoinAddress rootSeedRegular;
|
||||
NewcoinAddress rootGeneratorMaster;
|
||||
NewcoinAddress rootGeneratorRegular;
|
||||
NewcoinAddress reservedPublicRegular;
|
||||
NewcoinAddress reservedPrivateRegular;
|
||||
NewcoinAddress rootAddress;
|
||||
|
||||
rootSeedMaster.setFamilySeed(CKey::PassPhraseToKey("Master passphrase."));
|
||||
rootSeedRegular.setFamilySeed(CKey::PassPhraseToKey("Regular passphrase."));
|
||||
|
||||
std::cerr << "Master seed: " << rootSeedMaster.humanFamilySeed() << std::endl;
|
||||
std::cerr << "Regular seed: " << rootSeedRegular.humanFamilySeed() << std::endl;
|
||||
|
||||
rootGeneratorMaster.setFamilyGenerator(rootSeedMaster);
|
||||
rootGeneratorRegular.setFamilyGenerator(rootSeedRegular);
|
||||
|
||||
std::cerr << "Master generator: " << rootGeneratorMaster.humanFamilyGenerator() << std::endl;
|
||||
std::cerr << "Regular generator: " << rootGeneratorRegular.humanFamilyGenerator() << std::endl;
|
||||
|
||||
rootAddress.setAccountPublic(rootGeneratorMaster, 0);
|
||||
|
||||
std::cerr << "Regular address: " << rootAddress.humanAccountPublic() << std::endl;
|
||||
std::cerr << "Master seed: " << rootSeedMaster.humanFamilySeed() << std::endl;
|
||||
std::cerr << "Master generator: " << rootGeneratorMaster.humanFamilyGenerator() << std::endl;
|
||||
std::cerr << "Root address: " << rootAddress.humanAccountPublic() << std::endl;
|
||||
#if 0
|
||||
NewcoinAddress rootSeedRegular;
|
||||
NewcoinAddress rootGeneratorRegular;
|
||||
NewcoinAddress reservedPublicRegular;
|
||||
NewcoinAddress reservedPrivateRegular;
|
||||
|
||||
rootSeedRegular.setFamilySeed(CKey::PassPhraseToKey("Regular passphrase."));
|
||||
rootGeneratorRegular.setFamilyGenerator(rootSeedRegular);
|
||||
|
||||
reservedPublicRegular.setAccountPublic(rootGeneratorRegular, -1);
|
||||
reservedPrivateRegular.setAccountPrivate(rootGeneratorRegular, rootSeedRegular, -1);
|
||||
|
||||
std::cerr << "Reserved public regular: " << reservedPublicRegular.humanAccountPublic() << std::endl;
|
||||
std::cerr << "Reserved private regular: " << reservedPrivateRegular.humanAccountPrivate() << std::endl;
|
||||
|
||||
// hash of regular account #reserved public key.
|
||||
uint160 uiGeneratorID = reservedPublicRegular.getAccountID();
|
||||
|
||||
@@ -152,6 +146,11 @@ void Application::run()
|
||||
std::vector<unsigned char> vucGeneratorText = reservedPrivateRegular.accountPrivateDecrypt(reservedPublicRegular, vucGeneratorCipher);
|
||||
|
||||
std::cerr << "Plain: " << strHex(vucGeneratorText) << std::endl;
|
||||
std::cerr << "Regular seed: " << rootSeedRegular.humanFamilySeed() << std::endl;
|
||||
std::cerr << "Regular generator: " << rootGeneratorRegular.humanFamilyGenerator() << std::endl;
|
||||
std::cerr << "Reserved public regular: " << reservedPublicRegular.humanAccountPublic() << std::endl;
|
||||
std::cerr << "Reserved private regular: " << reservedPrivateRegular.humanAccountPrivate() << std::endl;
|
||||
#endif
|
||||
|
||||
// Temporary root account will be ["This is my payphrase."]:0
|
||||
NewcoinAddress rootFamilySeed; // Hold the 128 password.
|
||||
@@ -163,7 +162,6 @@ void Application::run()
|
||||
rootAddress.setAccountPublic(rootFamilyGenerator, 0);
|
||||
std::cerr << "Root account: " << rootAddress.humanAccountID() << std::endl;
|
||||
|
||||
|
||||
Ledger::pointer firstLedger = boost::make_shared<Ledger>(rootAddress, 100000000);
|
||||
assert(!!firstLedger->getAccountState(rootAddress));
|
||||
firstLedger->updateHash();
|
||||
|
||||
@@ -8,14 +8,14 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ "AccountRoot", ltACCOUNT_ROOT, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AuthorizedKey),STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Balance), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LastReceive), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LastTxn), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(WalletLocator),STI_HASH256, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(AuthorizedKey),STI_VL, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(WalletLocator),STI_HASH256, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
@@ -34,6 +34,13 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "GeneratorMap", ltGENERATOR_MAP, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(GeneratorID), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Nickname", ltNICKNAME, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
|
||||
enum LedgerEntryType
|
||||
{
|
||||
ltINVALID=-1,
|
||||
ltACCOUNT_ROOT=0,
|
||||
ltRIPPLE_STATE=1,
|
||||
ltNICKNAME=2
|
||||
ltINVALID =-1,
|
||||
ltACCOUNT_ROOT =0,
|
||||
ltRIPPLE_STATE =1,
|
||||
ltGENERATOR_MAP =2,
|
||||
ltNICKNAME =3
|
||||
};
|
||||
|
||||
struct LedgerEntryFormat
|
||||
|
||||
@@ -32,7 +32,7 @@ enum SOE_Field
|
||||
sfBorrower, sfLender, sfLimit, sfOfferCurrency, sfLedgerHash,
|
||||
sfLastReceive, sfLastTxn, sfNextRate, sfNextRateLgr, sfNextRateExp,
|
||||
sfNickname, sfMinimumOffer,
|
||||
sfAuthorizedKey,
|
||||
sfAuthorizedKey, sfGenerator, sfGeneratorID, sfAccountID,
|
||||
|
||||
// test fields
|
||||
sfTest1, sfTest2, sfTest3, sfTest4
|
||||
|
||||
@@ -38,14 +38,6 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit, int length
|
||||
mMiddleTxn.giveObject(new STUInt64("Fee", sit.get64()));
|
||||
|
||||
mInnerTxn = STObject(mFormat->elements, sit, "InnerTransaction");
|
||||
updateSourceAccount();
|
||||
}
|
||||
|
||||
void SerializedTransaction::updateSourceAccount()
|
||||
{
|
||||
NewcoinAddress a;
|
||||
a.setAccountPublic(peekSigningPubKey());
|
||||
mSourceAccount.setAccountID(a.getAccountID());
|
||||
}
|
||||
|
||||
int SerializedTransaction::getLength() const
|
||||
@@ -217,12 +209,25 @@ std::vector<unsigned char>& SerializedTransaction::peekSigningPubKey()
|
||||
return v->peekValue();
|
||||
}
|
||||
|
||||
const NewcoinAddress& SerializedTransaction::setSigningPubKey(const std::vector<unsigned char>& s)
|
||||
const NewcoinAddress& SerializedTransaction::setSigningPubKey(const NewcoinAddress& naSignPubKey)
|
||||
{
|
||||
mSignPubKey = naSignPubKey;
|
||||
|
||||
STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningPubKey));
|
||||
if (!v) throw std::runtime_error("corrupt transaction");
|
||||
v->setValue(s);
|
||||
updateSourceAccount();
|
||||
v->setValue(mSignPubKey.getAccountPublic());
|
||||
|
||||
return mSignPubKey;
|
||||
}
|
||||
|
||||
const NewcoinAddress& SerializedTransaction::setSourceAccount(const NewcoinAddress& naSource)
|
||||
{
|
||||
mSourceAccount = naSource;
|
||||
|
||||
STHash160* v = dynamic_cast<STHash160*>(mMiddleTxn.getPIndex(TransactionISourceID));
|
||||
if (!v) throw std::runtime_error("corrupt transaction");
|
||||
v->setValue(mSourceAccount.getAccountID());
|
||||
|
||||
return mSourceAccount;
|
||||
}
|
||||
|
||||
@@ -283,3 +288,4 @@ Json::Value SerializedTransaction::getJson(int options) const
|
||||
ret["Inner"] = mInnerTxn.getJson(options);
|
||||
return ret;
|
||||
}
|
||||
// vim:ts=4
|
||||
|
||||
@@ -16,14 +16,13 @@ public:
|
||||
typedef boost::shared_ptr<SerializedTransaction> pointer;
|
||||
|
||||
protected:
|
||||
NewcoinAddress mSignPubKey;
|
||||
NewcoinAddress mSourceAccount;
|
||||
TransactionType mType;
|
||||
STVariableLength mSignature;
|
||||
STObject mMiddleTxn, mInnerTxn;
|
||||
TransactionFormat* mFormat;
|
||||
|
||||
void updateSourceAccount();
|
||||
|
||||
public:
|
||||
SerializedTransaction(SerializerIterator& sit, int length); // -1=all remaining, 0=get from sit
|
||||
SerializedTransaction(TransactionType type);
|
||||
@@ -42,7 +41,7 @@ public:
|
||||
const std::vector<unsigned char>& peekSignature() const;
|
||||
void setSignature(const std::vector<unsigned char>& s);
|
||||
uint256 getSigningHash() const;
|
||||
|
||||
|
||||
// middle transaction functions
|
||||
uint32 getVersion() const;
|
||||
void setVersion(uint32);
|
||||
@@ -55,14 +54,15 @@ public:
|
||||
std::vector<unsigned char> getSigningPubKey() const;
|
||||
const std::vector<unsigned char>& peekSigningPubKey() const;
|
||||
std::vector<unsigned char>& peekSigningPubKey();
|
||||
const NewcoinAddress& setSigningPubKey(const std::vector<unsigned char>& s);
|
||||
const NewcoinAddress& setSigningPubKey(const NewcoinAddress& naSignPubKey);
|
||||
const NewcoinAddress& setSourceAccount(const NewcoinAddress& naSource);
|
||||
std::string getTransactionType() const { return mFormat->t_name; }
|
||||
|
||||
// inner transaction functions
|
||||
uint32 getFlags() const { return mInnerTxn.getFlags(); }
|
||||
void setFlag(uint32 v) { mInnerTxn.setFlag(v); }
|
||||
void clearFlag(uint32 v) { mInnerTxn.clearFlag(v); }
|
||||
|
||||
|
||||
uint32 getSequence() const;
|
||||
void setSequence(uint32);
|
||||
|
||||
@@ -116,3 +116,4 @@ public:
|
||||
};
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
|
||||
@@ -23,7 +23,14 @@ Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAd
|
||||
|
||||
mFromPubKey = fromLocalAccount->getPublicKey();
|
||||
assert(mFromPubKey);
|
||||
mTransaction->setSigningPubKey(mFromPubKey->GetPubKey());
|
||||
|
||||
// XXX Temporary: We don't really have local accounts.
|
||||
NewcoinAddress signPubKey;
|
||||
|
||||
signPubKey.setAccountPublic(mFromPubKey->GetPubKey());
|
||||
|
||||
mTransaction->setSigningPubKey(signPubKey);
|
||||
mTransaction->setSourceAccount(mAccountFrom);
|
||||
|
||||
mTransaction->setSequence(accountState->getSeq());
|
||||
assert(mTransaction->getSequence() != 0);
|
||||
@@ -105,6 +112,7 @@ Transaction::Transaction(const std::vector<unsigned char>& raw, bool validate) :
|
||||
mStatus = NEW;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,
|
||||
CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
|
||||
uint32 ident, const std::vector<unsigned char>& signature, uint32 ledgerSeq, TransStatus st) :
|
||||
@@ -113,7 +121,8 @@ Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toI
|
||||
mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT);
|
||||
mTransaction->setSignature(signature);
|
||||
mTransaction->setTransactionFee(fee);
|
||||
mTransaction->setSigningPubKey(pubKey->GetPubKey());
|
||||
mTransaction->setSigningPubKey(pubKey); // BROKEN
|
||||
mTransaction->setSourceAccount(mAccountFrom); // BROKEN
|
||||
mTransaction->setSequence(fromSeq);
|
||||
if (fromLedger != 0)
|
||||
{
|
||||
@@ -129,6 +138,7 @@ Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toI
|
||||
mTransaction->setITFieldAccount(sfDestination, toID.getAccountID());
|
||||
updateID();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Transaction::sign(LocalAccount::pointer fromLocalAccount)
|
||||
{
|
||||
|
||||
@@ -6,21 +6,63 @@
|
||||
TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn,
|
||||
TransactionEngineParams params)
|
||||
{
|
||||
TransactionEngineResult result = terSUCCESS;
|
||||
|
||||
uint256 txID = txn.getTransactionID();
|
||||
if(!txID) return terINVALID;
|
||||
|
||||
// extract signing key
|
||||
// Extract signing key
|
||||
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed
|
||||
// without going to disk. Each transaction also notes a source account id. This is used to verify that the signing key is
|
||||
// associated with the account.
|
||||
CKey acctKey;
|
||||
if (!acctKey.SetPubKey(txn.peekSigningPubKey())) return terINVALID;
|
||||
|
||||
// check signature
|
||||
if (!txn.checkSign(acctKey)) return terINVALID;
|
||||
|
||||
bool bPrepaid = false;
|
||||
|
||||
// Customize behavoir based on transaction type.
|
||||
switch(txn.getTxnType())
|
||||
{
|
||||
case ttCLAIM:
|
||||
bPrepaid = true;
|
||||
break;
|
||||
|
||||
case ttMAKE_PAYMENT:
|
||||
case ttINVOICE:
|
||||
case ttEXCHANGE_OFFER:
|
||||
result = terSUCCESS;
|
||||
break;
|
||||
|
||||
case ttINVALID:
|
||||
result = terINVALID;
|
||||
break;
|
||||
|
||||
default:
|
||||
result = terUNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (terSUCCESS != result)
|
||||
return result;
|
||||
|
||||
uint64 txnFee = txn.getTransactionFee();
|
||||
if ( (params & tepNO_CHECK_FEE) != tepNONE)
|
||||
{
|
||||
// WRITEME: Check if fee is adequate
|
||||
if (txnFee == 0) return terINSUF_FEE_P;
|
||||
if (bPrepaid)
|
||||
{
|
||||
if (txnFee)
|
||||
// Transaction is malformed.
|
||||
return terINSUF_FEE_P;
|
||||
}
|
||||
else
|
||||
{
|
||||
// WRITEME: Check if fee is adequate
|
||||
if (txnFee == 0)
|
||||
return terINSUF_FEE_P;
|
||||
}
|
||||
}
|
||||
|
||||
// get source account ID
|
||||
@@ -30,39 +72,59 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
|
||||
|
||||
// find source account
|
||||
// If we are only verifying some transactions, this would be probablistic.
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SerializedLedgerEntry::pointer src = mLedger->getAccountRoot(qry, srcAccount);
|
||||
if (!src) return terNO_ACCOUNT;
|
||||
|
||||
// deduct the fee, so it's not available during the transaction
|
||||
// we only write the account back if the transaction succeeds
|
||||
uint64 balance = src->getIFieldU64(sfBalance);
|
||||
if (balance < txnFee)
|
||||
return terINSUF_FEE_B;
|
||||
src->setIFieldU64(sfBalance, balance - txnFee);
|
||||
|
||||
// validate sequence
|
||||
uint32 t_seq = txn.getSequence();
|
||||
uint32 a_seq = src->getIFieldU32(sfSequence);
|
||||
if (t_seq != a_seq)
|
||||
if (txnFee)
|
||||
{
|
||||
// WRITEME: Special case code for changing transaction key
|
||||
if (a_seq < t_seq) return terPRE_SEQ;
|
||||
if (mLedger->hasTransaction(txID))
|
||||
return terALREADY;
|
||||
return terPAST_SEQ;
|
||||
uint64 balance = src->getIFieldU64(sfBalance);
|
||||
|
||||
if (balance < txnFee)
|
||||
return terINSUF_FEE_B;
|
||||
|
||||
src->setIFieldU64(sfBalance, balance - txnFee);
|
||||
}
|
||||
|
||||
// Validate sequence
|
||||
uint32 t_seq = txn.getSequence();
|
||||
|
||||
if (bPrepaid)
|
||||
{
|
||||
if (t_seq)
|
||||
return terPAST_SEQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 a_seq = src->getIFieldU32(sfSequence);
|
||||
|
||||
if (t_seq != a_seq)
|
||||
{
|
||||
// WRITEME: Special case code for changing transaction key
|
||||
if (a_seq < t_seq) return terPRE_SEQ;
|
||||
if (mLedger->hasTransaction(txID))
|
||||
return terALREADY;
|
||||
return terPAST_SEQ;
|
||||
}
|
||||
else src->setIFieldU32(sfSequence, t_seq);
|
||||
}
|
||||
else src->setIFieldU32(sfSequence, t_seq);
|
||||
|
||||
std::vector<AffectedAccount> accounts;
|
||||
accounts.push_back(std::make_pair(taaMODIFY, src));
|
||||
TransactionEngineResult result = terUNKNOWN;
|
||||
|
||||
switch(txn.getTxnType())
|
||||
{
|
||||
case ttINVALID:
|
||||
result = terINVALID;
|
||||
break;
|
||||
|
||||
case ttCLAIM:
|
||||
result = doClaim(txn, accounts);
|
||||
break;
|
||||
|
||||
case ttMAKE_PAYMENT:
|
||||
result = doPayment(txn, accounts);
|
||||
break;
|
||||
@@ -110,6 +172,12 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
return result;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
return terUNKNOWN;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ enum TransactionEngineResult
|
||||
terUNFUNDED, // Source account had insufficient balance for transactin
|
||||
terNO_PATH, // No path existed or met transaction/balance requirements
|
||||
terPAST_SEQ, // This sequence number has already past
|
||||
terBAD_SEQ, // This sequence number should be zero for prepaid transactions.
|
||||
terPRE_SEQ, // Missing/inapplicable prior transaction
|
||||
terPAST_LEDGER, // The transaction expired and can't be applied
|
||||
};
|
||||
@@ -51,13 +52,14 @@ class TransactionEngine
|
||||
protected:
|
||||
Ledger::pointer mLedger;
|
||||
|
||||
TransactionEngineResult doPayment(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doCancel(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doClaim(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doDelete(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doInvoice(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doOffer(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doTake(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doCancel(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doPayment(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doStore(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doDelete(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
TransactionEngineResult doTake(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||
|
||||
public:
|
||||
TransactionEngine() { ; }
|
||||
|
||||
@@ -16,6 +16,13 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Claim", ttCLAIM, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(GeneratorID), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Invoice", ttINVOICE, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
|
||||
enum TransactionType
|
||||
{
|
||||
ttINVALID=-1,
|
||||
ttMAKE_PAYMENT=0,
|
||||
ttINVOICE=1,
|
||||
ttEXCHANGE_OFFER=2
|
||||
ttINVALID = -1,
|
||||
ttMAKE_PAYMENT = 0,
|
||||
ttCLAIM = 1,
|
||||
ttINVOICE = 2,
|
||||
ttEXCHANGE_OFFER = 3
|
||||
};
|
||||
|
||||
struct TransactionFormat
|
||||
@@ -18,10 +19,14 @@ struct TransactionFormat
|
||||
SOElement elements[16];
|
||||
};
|
||||
|
||||
const int32 TransactionMagic=0x54584E00;
|
||||
const int32 TransactionMagic = 0x54584E00; // 'TXN'
|
||||
|
||||
const int TransactionIVersion=0, TransactionISigningPubKey=1, TransactionISequence=2;
|
||||
const int TransactionIType=3, TransactionIFee=4;
|
||||
const int TransactionIVersion = 0;
|
||||
const int TransactionISigningPubKey = 1;
|
||||
const int TransactionISourceID = 2;
|
||||
const int TransactionISequence = 3;
|
||||
const int TransactionIType = 4;
|
||||
const int TransactionIFee = 5;
|
||||
|
||||
const int TransactionMinLen=32;
|
||||
const int TransactionMaxLen=1048576;
|
||||
|
||||
Reference in New Issue
Block a user