BTCBTC引入了许多创新的概念和技术。区块链、PoW共识、RSA加密、智能合约等处于萌芽阶段的术语经常被业内人士提及,而且,这些创新的实现确实让BTC变成了一个具有可靠性和安全性保障的封闭生态系统,但在这个BTC生态系统,如果没有区块链模式的转账模块,那么货币的流通属性也就无从谈起。实现转账交易模块,“是否使用传统账户模型实现交易;交易信息如何存储在区块链上,如何实现信息压缩;交易信息如何验证;系统最大并发交易量”和其他问题确实值得思考。BTC将这些一一解决。它摒弃了传统的基于账户的交易模型,而是采用基于区块链存储的utxo(未花费交易输出)模型。笔者尝试分析为什么不用传统的账户模型:BTC的存储单位是区块链,而区块链的数据结构本质上是一个单向链表。不是传统的关系型数据库,不可能新建一个账表来存储压力。如果采用传统的方式,随着时间的推移,账户表会不断增长,这会给后续的表分片和备份带来很大的困难,容易导致隐私泄露。account表中的信息会很直观的暴露余额等敏感信息,但是utxo模型非常巧妙的避免了这一点。utxo模型下实现的每一笔交易都不需要显式提供转账地址和接收地址(没有账户,也不需要提供地址),只需要提供交易的交易输入和交易输出,以及什么是交易输入和交易输出?交易输入指向一个交易输出,“这个交易输出可以被转账方消费,所以这个交易输出也叫utxo(unspenttransactionoutput)”,其中包括“某笔交易,指向这个的一个索引值交易的可用交易输出和解锁脚本”。该解锁脚本用于验证提供解锁脚本的人是否可以使用可用的消费输出。交易输出是一个存储BTC“余额”的数据结构,大致包括两部分:BTC数量和锁定脚本。BTC的数量可以理解为余额,代表交易的结果;而锁定脚本是通过一定的算法来锁定BTC余额,直到有人可以提供数据密钥来解锁脚本,BTC数量才会被锁定。被人消费。从这个角度来看,一笔交易会包含若干笔交易输入,同时会产生若干笔交易输出。这些交易输入会指向前一笔交易未被消费的输出(utxo),并提供自己的解锁脚本来证明这些utxo中的BTC属于转账方;同时,转账产生的所有交易输出都会用对应方的公钥进行加密(这里为了更好理解理解为公钥加密,本质上是一个公钥哈希,即一串reversebase58encodedbtcaddresses),锁定这些交易输出,并等待交易输入解锁脚本解锁。因此,BTC没有账户的概念,所有的“余额”都在区块链上,只是这些余额已经加密,只有提供私钥和签名的人才能使用对应的utxo余额,所以这就是为什么BTC的原因持有者必须保留自己的私钥。UTXO的node.js实现交易输入exportclassInput{privatetxId:string;私有输出索引:数字;私人解锁脚本:字符串;publicget$txId():string{返回this.txId;}publicset$txId(value:string){this.txId=value;}publicget$outputIndex():number{returnthis.outputIndex;}publicset$outputIndex(value:number){this.outputIndex=value;}publicget$unlockScript():string{returnthis.unlockScript;}publicset$unlockScript(value:string){this.unlockScript=value;}constructor(txId:string,index:number,unlockScript:string){this.txId=txId;this.outputIndex=索引;this.unlockScript=unlockScript;}//反序列表化,进行类型转换publicstaticcreateInputsFromUnserialize(objs:Array){letins=[];objs.forEach((obj)=>{ins.push(新输入(obj.txId,obj.outputIndex,obj.解锁脚本));});返回插件;}canUnlock(privateKey:string):boolean{if(privateKey==this.unlockScript){returntrue;}else{返回错误;}}}私有属性txId标识“一个可用的utxo所属的交易”是一串sha256编码的字符串;outputIndex表示“可用的utxo对应交易的序号值”;unlockScript即解锁脚本,并没有完全按照BTC的原型实现,只是简单的验证用户的私钥来实现鉴权,原则上还是沿用了BTC的思路交易输出import*asrsaConfigfrom'../../rsa.json';exportclassOutput{privatevalue:number;//锁定脚本,需要使用UTXO所有者用私钥签名Pass//当解锁UTXO成功后,这个UTXO成为下一笔交易的交易输入,同时锁定本次交易的交易输出usingreceiver'saddress(publickey),//等待接收方使用私钥签名来使用UTXO//所以没有btc账户的概念所有“钱”的概念都是自己公钥加密保存key,只有自己的私钥才能使用这笔钱(即解锁UTXO的解锁脚本)privatelockScript:string;//该属性仅在交易期间使用,设置属性privatetxId:string;//该属性仅在交易中使用,设置属性privateindex:number;publicget$index():number{returnthis.index;}publicset$index(value:number){this.index=value;}publicget$txId():string{returnthis.txId;}publicset$txId(value:string){this.txId=value;}publicget$value():number{returnthis.value;}publicset$value(value:number){this.value=value;}/*publicget$lockScript():string{returnthis.lockScript;}publicset$lockScript(value:string){这个。锁定脚本=价值;}*/constructor(value:number,publicKey:string){this.value=value;this.lockScript=publicKey;}//反序列化并进行类型转换publicstaticcreateOnputsFromUnserialize(objs:Array