-
Notifications
You must be signed in to change notification settings - Fork 4
Transaction
TowardsFree edited this page Mar 7, 2019
·
9 revisions
| 源文件 | 类 |
|---|---|
| transaction.h destination.h | CTransaction CTxOutPoint CTxIn CDestination CTxOutput |
FnFn链采用与比特币一致的 UTXO 模型记录交易,弱化了账户的概念。CTransaction类表示一笔交易,类成员有如下字段:
uint16 nVersion; //版本号,目前交易版本为 0x0001
uint16 nType; // 类型, 区分公钥地址交易、模板地址交易、即时业务交易和跨分支交易
uint32 nLockUntil; // 交易冻结至高度为 nLockUntil 区块
uint256 hashAnchor; // 交易有效起始区块 HASH
std::vector<CTxIn> vInput; // 前序交易输出列表,包含前序交易 ID 和输出点序号
CDestination sendTo; // 输出地址
int64 nAmount; // 输出金额
int64 nTxFee; // 网络交易费
std::vector<uint8> vchData; // 输出参数(模板地址参数、跨分支交易共轭交易)
std::vector<uint8> vchSig; // 交易签名- nType字段表示此交易的类型,以enum class的方式表示:
enum
{
TX_TOKEN = 0x0000, // 常规的代币交易
TX_CERT = 0xff00, // 委托交易
TX_GENESIS = 0x0100, // 创世区块的coinbase交易
TX_STAKE = 0x0200, // DPOS共识出块的coinbase交易
TX_WORK = 0x0300, // POw共识出块的coinbase交易
};- hashAnchor字段,用于指明当前交易适用于特定一个或多个分支。
- vInput,就是UTXO模型中的多个交易的输入,也就是资金来源,就是前序交易的UTXO输出,用(PreTxId,nIndex)二元结构表示一个输入或是前序交易的输出。
- sendTo, 输出地址,也就是资金的去向。可以简单理解为钱包地址或者模板ID,但是实际上是一个公钥地址+公钥前缀(0x01)或模板ID+模板前缀(0x02),因为钱包的地址是通过对钱包公钥作Hash和最后做一道Base32编码转换成的可读的文本表示。
- nAmount,输出金额,也就是该交易所有输出的总计(合)。
- nTxFee,交易费,相当于给矿工的钱,最后需要打包到Block中的txMint字段中
注意: 输入输出中隐含了找零机制,关系是 : 找零 = vInput - nAmount - nTxFee
- vchData, 输出参数(模板地址参数、跨分支交易共轭交易) 待定,暂时不很清楚详细用途,白皮书看不明白。模板很类似BTC中的脚本。
- vchSig, 交易签名
- CTxIn 表示交易的一条输入,对应前序交易的一个UTXO输出,其实CTxIn类就以复合方式(没用继承)复用了CTxOutPoint类
- CDestination 表示交易的一个输出地址
- CTxOutPoint 表示一个输出,以(wallet_pubkey,nIndex)这样的二元结构表示一个输出
- CTxOutput 表示一个输出所输出的Detail,比如输出额度(nAmount),输出地址(CDestination)等。
- CTransaction表示一个交易,一个交易可能有多个输入和多个输出
- CTxUnspent 表示一个UTXO, 继承了CTxOutPoint类,以复合方式复用了CTxOutput类,也就是输出的Detail
- CAssembledTx 表示一个已经被打包进区块的交易,继承了CTransaction。
- CTxIndex 表示一个交易的索引,把一个交易与本地节点存储的文件和偏移关联上,用于快速定位查找块文件中的交易
- 设置交易为空
void SetNull()- 判断交易是否为空,通过输入是否为空和输出地址是否为空作为判断依据
bool IsNull() const;- 判断交易类型是否是矿机器交易
bool IsMintTx() const;- 得到交易类型的可读的文本表示
std::string GetTypeString() const- 得到交易的Hash,对交易的所有二进制数据作Hash
uint256 GetHash() const
{
walleve::CWalleveBufStream ss;
ss << (*this);
return multiverse::crypto::CryptoHash(ss.GetData(),ss.GetSize());
}- 得到签名Hash,对除去vchSig字段以外的所有字段Hash。
uint256 GetSignatureHash() const
{
walleve::CWalleveBufStream ss;
ss << nVersion << nType << nLockUntil << hashAnchor << vInput << sendTo << nAmount << nTxFee << vchData;
return multiverse::crypto::CryptoHash(ss.GetData(),ss.GetSize());
}- 得到找零的金额。
int64 GetChange(int64 nValueIn) const
{
return (nValueIn - nAmount - nTxFee);
}- 清空输出
void SetNull();- 判断输出是否为空。
bool IsNull() const ;- 判断输出是否被锁住了。
bool IsLocked(int nBlockHeight) const { return (nBlockHeight < nLockUntil); } 如果传入的块高度比冻结高度小,那么就被锁住了。
- 把输出转换为字符串的形式
std::string ToString() const ;输出的字符串形式为以下形式(输出地址的十六进制字符串,输出的额度,冻结至区块高度):
TxOutput : (12a2b124c214ccdef , 0.1 , 25231 )
- 设置交易为空
void SetNull();- 计算找零
int64 GetChange() const
{
return (nValueIn - nAmount - nTxFee);
}- 通过输出的序号得到相应的输出
const CTxOutput GetOutput(int n=0) const
{
if (n == 0)
{
return CTxOutput(sendTo,nAmount,nLockUntil);
}
else if (n == 1)
{
return CTxOutput(destIn,GetChange(),0);
}
return CTxOutput();
}输入参数为0的时候得到的是发送给别的钱包的输出。 输入参数为1的时候得到的是给自己钱包找零的输出。 如果输入参数为其他,那么构造的是空的输出。
- 获取交易的所有输入金额总和
int64 GetValueIn() const
{
int64 nValueIn = 0;
for (int i = 0;i < vInputValue.size();i++)
{
nValueIn += vInputValue[i].first;
}
return nValueIn;
}| 整理者 | 日期 |
|---|---|
| Shaohan Chen | to be continue |
Home | Copyright © 2017-2019 FissionAndFusion