银行系统账户更新
银行系统在资金交易方面的操作较为直接。一旦有交易发生,无论处于何种时间和地点,银行都会即刻更新用户账户的余额字段。例如在 2024 年 3 月 10 日北京的某家银行,用户 A 向用户 B 转账 5000 元,银行系统会迅速将用户 A 的账户余额减少 5000 元,同时用户 B 的余额也会相应增加。这种方式简单高效,能让用户及时知道自己账户资金情况。
银行系统历经多年发展,逐渐形成了固定的模式。大型国有银行如此,小型地方银行也是如此,它们都依据这一规则来处理交易。这样一来,人们在进行日常转账等业务时,就能够清晰地知晓资金的变动情况,从而保证了日常生活中资金交易能够有序地进行。
比特币数据库与银行系统不同,其中只有交易信息,不存在用户帐号信息。在比特币网络中,不管你是在纽约还是在东京进行交易,系统所记录的仅仅是交易这一行为本身。就如同一个账本,它只记录事件的过程,而不会记录当事人的身份。有一位比特币爱好者在 2023 年底进行了比特币交易,整个过程只显示交易的细节,无法从数据库中直接得知交易的双方究竟是谁。
这种设计存在一定益处。其一,它提升了交易的匿名性,能为比特币用户提供更多的隐私保障。其二,它也带来了一些难题,比如无法直接从数据库里知晓某个用户的所有交易状况,要查找特定用户的相关交易就会变得较为复杂。
比特币交易基础规则
在比特币系统里,每一笔交易都依托于之前的交易。例如在 2024 年初的时候,用户 C 接收到了一笔比特币的转账。当他之后要对这笔比特币进行交易时,系统就需要去确认前面那笔转账是否已经生效。这就好像盖房子一样,需要层层递进,每一层都是以下面的那一层作为基础的。这种规则使得比特币的交易形成了一条相互紧密关联的链条。
这一规则确保了比特币交易具有连贯性以及可追溯性。每一笔交易的来源与去向都能够依据前面的交易而被追踪到。然而,这也就意味着倘若要对某笔交易进行查询,或许就需要去查询前面数量众多的交易记录,从而增加了查询所耗费的时间以及难度。
比特币余额统计方式
在比特币系统当中,若要知晓某个钱包地址的余额,就必须遍历整个账本。在过去的一个月时间里,有一位研究人员,他想要统计一个特定钱包地址的余额,为此花费了不少时间去对每一笔相关的交易进行梳理。与银行系统能够直接查看账户余额有所不同,比特币系统仅仅能够通过对属于该地址的所有交易进行统计,才能够确定其余额。
type TXInput struct {
TXID []byte // 引用输出的交易ID
OutputIndex int64 // 引用输出的索引
//ScriptSig string // 解锁脚本(实际上这里应该是签名和公钥)
Signature []byte // 签名
PubKey []byte // 公钥
}
type TXOutput struct {
Value float64 // 金额
//ScriptPubKey string // 锁定脚本(公钥哈希)
PubKeyHash []byte // 公钥哈希
}
type Transaction struct {
TXID []byte // 交易ID
Inputs []TXInput // 交易输入
Outputs []TXOutput // 交易输出
}
这种统计方式能保证余额的准确性,不过效率较为低下。尤其是在比特币交易日益频繁的情况下,这种情况更为明显。并且对于普通用户而言,这种复杂的统计过程他们很难独自完成,通常需要借助专业的工具或者平台来进行。
// 设置交易ID
func (tx *Transaction) SetHash() {
// 对tx进行加密处理,生成字节流
var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)
encoder.Encode(&tx)
// 使用sha256对字节流再次假面,生成一个hash值
data := buffer.Bytes()
hash := sha256.Sum256(data)
// 把hash作为交易的ID
tx.TXID = hash[:]
}
比特币交易的输入输出
const reward = 50 // 挖矿奖励
// 创建挖矿交易
// 参数一:矿工地址
// 参数二:矿工附加信息
func NewCoinBaseTx(address string, data string) *Transaction {
input := TXInput{nil, -1, data}
output := TXOutput{reward, address}
tx := Transaction{nil, []TXInput{input}, []TXOutput{output}}
tx.SetHash()
return &tx
}
比特币交易由输入和输出两部分构成。拿张三给李四转账这件事来说,系统生成的输出当中包含“转账金额”以及“锁定脚本”。“锁定脚本”就仿佛是一把特殊的锁,只有李四的私钥才能够将其解开。倘若李四要给王五转账,就会创建输入,输入里面包含所引用交易的 ID 以及签名和公钥。在 2024 年 4 月的那一次交易里,就把这样的流程体现了出来。
// 定义区块
type Block struct {
// 版本号
Version uint64
// 前区块哈希值
PrevHash []byte
// 梅克尔根
MerKleRoot []byte
// 时间戳
TimeStamp uint64
// 难度值
Difficulty uint64
//随机数
Nonce uint64
// 当前区块哈希值
Hash []byte
// 区块数据
//Data []byte
Data []*Transaction // 区块的交易数据
}
这种方式使比特币交易具备了更高的安全性与灵活性。借助输入输出机制以及锁定、解锁脚本,就能够确保只有持有相应私钥的人才能动用比特币。与此同时,引用交易 ID 还保证了交易的连贯性以及可追溯性。
// 创建方法
func NewBlock(data []*Transaction, prevHash []byte) *Block {
block := Block{
Version: 00,
PrevHash: prevHash,
MerKleRoot: []byte{},
TimeStamp: uint64(time.Now().Unix()),
Difficulty: 1,
Nonce: 1,
//Data: []byte(data),
Data: data,
}
//提供一个设置哈希的方法
//block.SetHash()
pow := NewProofOfWork(block)
hash, nonce := pow.Run()
block.Hash = hash
block.Nonce = nonce
return &block
}
未消费输出相关概念
未消费输出(UTXO)是比特币交易的最小支付单位。它无法被分割,必须一次性全部消耗完,之后才能在比特币网络的 UTXO 池中生成新的 UTXO。2023 年 11 月,有一位用户进行交易时使用了多个 UTXO,每一个 UTXO 都得全部用完。用户的比特币余额是由钱包应用将所有属于该用户的 UTXO 进行聚合后计算得出的。
// 创建方法
//func NewBlockChain() *BlockChain {
func NewBlockChain(address string) *BlockChain {
/*// 创建创世块
genericBlock := NewBlock([]byte(genesisInfo), []byte{})
// 创建BlockChain
bc := BlockChain{[]*Block{genericBlock}}
return &bc*/
var db *bolt.DB
var lastHash []byte
// 1. 打开数据库
db, err := bolt.Open(dbName, 0600, nil)
if err != nil {
panic("bolt.Open err!")
}
db.Update(func(tx *bolt.Tx) error {
// 2. 打开抽屉Bucket
bucket := tx.Bucket([]byte(bucketName))
// 3. 如果Bucket是否为nil,则创建一个Bucket
if bucket == nil {
bucket, err = tx.CreateBucket([]byte(bucketName))
if err != nil {
panic("tx.CreateBucket err!")
}
// 创建创世块
//genericBlock := NewBlock([]byte(genesisInfo), []byte{})
//创建coinbase交易 <---这里修改
coinbaseTx := NewCoinBaseTx(address, genesisInfo)
//创建创世块 <---这里修改
genericBlock := NewBlock([]*Transaction{coinbaseTx}, []byte{})
// 把创世块保存在bucket中
bucket.Put(genericBlock.Hash, genericBlock.Serialize())
// 把创世块的hash保存在last中
bucket.Put([]byte(last), genericBlock.Hash)
// 记录lastHash
lastHash = genericBlock.Hash
} else {
// 4. 如果Bucket不为nil,记录lastHash
lastHash = bucket.Get([]byte(last))
}
return nil
})
return &BlockChain{db, lastHash}
}
UTXO 机制确保了比特币交易的清晰性与准确性。每一个交易的源头以及去向,都能够借助 UTXO 得以明确,从而避免了交易过程中的混乱状况。然而,这也使得用户在进行交易时,需要合理地对自己的 UTXO 进行管理,否则就有可能出现交易无法顺利开展的情形。
// 添加区块
//func (bc *BlockChain) AddBlock(data string) {
func (bc *BlockChain) AddBlock(txs []*Transaction) {
/*// 获取最后区块
lastBlock := bc.Blocks[len(bc.Blocks)-1]
// 创建一个新区块
block := NewBlock([]byte(data), lastBlock.Hash)
// 添加新区块
bc.Blocks = append(bc.Blocks, block)*/
// 获取最后区块hash
lastHash := bc.Tail
// 创建区块
//block := NewBlock([]byte(data), lastHash)
block := NewBlock(txs, lastHash)
// 更新操作
bc.Db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(bucketName))
if bucket == nil {
panic("bucket should not be nil!")
}
// 向bolt数据库添加新区块
bucket.Put(block.Hash, block.Serialize())
// 更新数据库的last
bucket.Put([]byte(last), block.Hash)
// 更新bc.Tail
bc.Tail = block.Hash
return nil
})
}
你认为比特币这种复杂的交易机制会给它的未来发展带来怎样的影响?大家可以点赞、分享本文,并且在评论区留言进行讨论。
// 根据nonce生成区块哈希,该方法与SetHash方法类似
func (pow *ProofOfWork) PrepareData(nonce uint64) []byte {
block := pow.Block
block.MerKleRoot = block.HashTransactions()
tmp := [][]byte{
block.PrevHash,
//block.Data,
block.MerKleRoot,
uint64ToByte(block.Version),
uint64ToByte(block.TimeStamp),
uint64ToByte(block.Difficulty),
uint64ToByte(nonce),
}
blockInfo := bytes.Join(tmp, []byte{})
// 2.使用sha256加密
hash := sha256.Sum256(blockInfo)
return hash[:]
}
转载请注明出处:usdt钱包官方下载,如有疑问,请联系()。
本文地址:https://www.hrbaixh.com/toqb/1554.html