#include "Transaction.h" #include "Wallet.h" #include "Account.h" #include "BitcoinUtil.h" using namespace std; Transaction::Transaction() : mTransactionID(0), mAccountFrom(0), mAccountTo(0), mAmount(0), mFromAccountSeq(0), mSourceLedger(0), mIdent(0), mInLedger(0), mStatus(INVALID) { } Transaction::Transaction(TransStatus status, LocalAccount& fromLocalAccount, uint32 fromSeq, const uint160& toAccount, uint64 amount, uint32 ident, uint32 ledger) : mAccountTo(toAccount), mAmount(amount), mFromAccountSeq(fromSeq), mSourceLedger(ledger), mIdent(ident), mInLedger(0), mStatus(NEW) { assert(fromLocalAccount.mAmount>=amount); mAccountFrom=fromLocalAccount.getAddress(); updateFee(); mFromPubKey.SetPubKey(fromLocalAccount.peekPubKey().GetPubKey()); sign(fromLocalAccount); } Transaction::Transaction(const std::vector &t, bool validate) : mStatus(INVALID) { Serializer s(t); if(s.getLength()<145) { assert(false); return; } if(!s.get160(mAccountTo, 0)) { assert(false); return; } if(!s.get64(mAmount, 20)) { assert(false); return; } if(!s.get32(mFromAccountSeq, 28)) { assert(false); return; } if(!s.get32(mSourceLedger, 32)) { assert(false); return; } if(!s.get32(mIdent, 36)) { assert(false); return; } if(!s.getRaw(mSignature, 69, 72)) { assert(false); return; } std::vector pubKey; if(!s.getRaw(pubKey, 40, 33)) { assert(false); return; } if(!mFromPubKey.SetPubKey(pubKey)) { assert(false); return; } updateID(); if(validate && !checkSign()) { assert(false); return; } mStatus=NEW; } bool Transaction::sign(LocalAccount& fromLocalAccount) { if( (mAmount==0) || (mSourceLedger==0) || (mAccountTo==0) ) { assert(false); return false; } if(mAccountFrom!=fromLocalAccount.mAddress.GetHash160()) { assert(false); return false; } Serializer::pointer signBuf=getRaw(true); assert(signBuf->getLength()==73+4); if(!signBuf->makeSignature(mSignature, fromLocalAccount.peekPrivKey())) { assert(false); return false; } assert(mSignature.size()==72); updateID(); return true; } void Transaction::updateFee() { // for now, all transactions have a 1,000 unit fee mFee=1000; } bool Transaction::checkSign() const { return mFromPubKey.Verify(getRaw(true)->getSHA512Half(), mSignature); } Serializer::pointer Transaction::getRaw(bool prefix) const { Serializer::pointer ret(new Serializer(77)); if(prefix) ret->add32(0x54584e00u); ret->add160(mAccountTo); ret->addRaw(mFromPubKey.GetPubKey()); ret->add64(mAmount); ret->add32(mFromAccountSeq); ret->add32(mInLedger); ret->add32(mIdent); assert( (prefix&&(ret->getLength()==77)) || (!prefix&&(ret->getLength()==73)) ); return ret; } Serializer::pointer Transaction::getSigned() const { Serializer::pointer ret(getRaw(false)); ret->addRaw(mSignature); return ret; } void Transaction::updateID() { mTransactionID=getSigned()->getSHA512Half(); } void Transaction::setStatus(TransStatus ts, uint32 lseq) { mStatus=ts; mInLedger=lseq; }