Bitcoin in Go: https://github.com/btcsuite/
Building Blockchain in Go. 使用 Golang 建構區塊鏈
https://jeiwan.cc/
Part 1: Basic Prototype 基本原型
https://jeiwan.cc/posts/building-blockchain-in-go-part-1/
https://annatarhe.github.io/2017/12/29/building-blockchain-in-go-part-1-basic-prototype.html
https://github.com/Jeiwan/blockchain_go/tree/part_1
完整程式碼的演示:https://play.golang.org/p/6zOWpS_Yna0
Part 2: Proof-of-Work 工作量證明
https://jeiwan.cc/posts/building-blockchain-in-go-part-2/
https://annatarhe.github.io/2017/12/30/building-blockchain-in-go-part-2-proof-of-work.html
https://github.com/Jeiwan/blockchain_go/tree/part_2
合併程式碼 (Ctrl+S 存檔到本機後編譯才能運作):https://play.golang.org/p/JFBU1hWQkhQ
Part 3: Persistence and CLI 持久化與命令行
https://jeiwan.cc/posts/building-blockchain-in-go-part-3/
https://annatarhe.github.io/2017/12/30/building-blockchain-in-go-part-3-persistence-and-cli.html
https://github.com/Jeiwan/blockchain_go/tree/part_3
https://github.com/Jeiwan/blockchain_go/tree/part_3
合併程式碼 (Ctrl+S 存檔到本機後編譯才能運作):https://play.golang.org/p/xIk3j-_mLTd
比特幣的數據儲存方式 blk.dat:https://21st.each1.net/2019/12/blkdat.html
Part 4: Transactions 1 交易 1比特幣的數據儲存方式 blk.dat:https://21st.each1.net/2019/12/blkdat.html
https://jeiwan.cc/posts/building-blockchain-in-go-part-4/
https://annatarhe.github.io/2018/01/01/build-blockchain-in-go-part-4-transactions-1.html
https://github.com/Jeiwan/blockchain_go/tree/part_4
合併程式碼,並添加了部分修正 (Ctrl+S 存檔到本機後編譯才能運作):
https://play.golang.org/p/AGudHIBN6WG
在 func (cli *CLI) printChain() 中 加入更完整的區塊細節打印
Part 5: Addresses 地址
https://jeiwan.cc/posts/building-blockchain-in-go-part-5/
https://annatarhe.github.io/2018/01/02/building-blockchain-in-go-part-5-addresses.html
https://cordate.github.io/2018/03/28/blockchain/%E6%AF%94%E7%89%B9%E5%B8%81/Bitcoin%E4%B8%ADBase58Check/
https://github.com/Jeiwan/blockchain_go/tree/part_5
合併程式碼 (Ctrl+S 存檔到本機後編譯才能運作):https://play.golang.org/p/e4Ws_uN-Yrl
Part 6: Transactions 2 交易 2
https://jeiwan.cc/posts/building-blockchain-in-go-part-6/
https://annatarhe.github.io/2018/01/06/building-blockchain-in-go-part-6-transactions-2.html
https://github.com/Jeiwan/blockchain_go/tree/part_6
合併程式碼 (Ctrl+S 存檔到本機後編譯才能運作):https://play.golang.org/p/yEo5xdfDKvA
Part 7: Network 網絡
https://jeiwan.cc/posts/building-blockchain-in-go-part-7/
https://annatarhe.github.io/2018/01/12/building-blockchain-go-part-7-network.html
https://github.com/Jeiwan/blockchain_go/tree/part_7
合併程式碼,並添加了教程說明中所需要的環境變數 (Ctrl+S 存檔到本機後編譯才能運作):https://play.golang.org/p/rII18zokMTv
在 func main() 中加入 os.Setenv("NODE_ID", "3000")
最新版本:
https://github.com/Jeiwan/blockchain_go/tree/master
修正了比特幣存在多種版本的地址格式:https://21st.each1.net/2019/07/blog-post_7.html
從 Part 4 之後的範例,實測後發現 bugs,當同一個 address 自己轉給自己,查詢餘額時會發現餘額增加... 透過打印出完整的區塊細節,可以先找出一個 bug 發生的地方,然後可以再延伸出其他 bugs...
檢查後發現,這些 bugs 的起因是由於 returns a list of transactions containing unspent outputs 這個部分的函數,
當同一個地址自己轉給自己時,會在同一個 transaction 內生成兩個相同地址的 outputs (一個是轉帳的金額,一個是找零),
但是當後續的交易再引用上述 outputs 時,若只用到同一個 transaction 內的其中一個 output 時,該 transaction 仍然會被列在 list of transactions containing unspent outputs 內,然後後續的程式流程卻誤以為這個 transaction 內的所有 outputs 都是 unspent,因而導致了可用餘額憑空增加。
從代碼來看,就是從下面這個方法開始的邏輯流程發生錯誤
func (bc *Blockchain) FindUnspentTransactions(address string) []Transaction {
}
除錯後,總共修正了三個函數:
https://play.golang.org/p/YpFzoFvFLHK
整併為
https://play.golang.org/p/SA_55kFhOtq
Part 7 實測後發現許多 bugs,比如說相同節點的多筆帳戶互轉、同節點的多筆帳戶互轉相同金額,同一個地址轉給自己等等...
檢查後發現,
相同節點的多筆帳戶互轉、同一個地址轉給自己 的 bugs 是延續 Part4 的問題...
而其他問題比如說同一個地址轉帳給兩個帳戶,然後才一起挖掘時,會去引用同一筆輸出,導致雙花 (double spending) ...
綜合來看,是文中所提及還沒有完成的諸多工作,比如說應該驗證『區塊內的交易是否符合規則』。
以比特幣的做法來說,比特幣的雙重支付意味著一筆幣(UTXO)被花費了兩次。通常,這意味著A將她的0.413 BTC發送給了B,然後她又把同一筆比特幣又發送給了C。
比特幣的解決方法是,其中一筆交易會納入一個區塊,由此來決定實際誰得到了報酬。如果兩筆交易不知何故都傳遞到了多個區塊,那麼後面發生的區塊,就會被軟件給拒絕掉。如果兩筆交易都在同一個區塊當中,那麼這個區塊也會遭到軟件的拒絕。
Code your own blockchain in less than 200 lines of Go
所有教程的完整代碼
https://github.com/mycoralhealth/blockchain-tutorial
https://medium.com/@mycoralhealth/code-your-own-blockchain-in-less-than-200-lines-of-go-e296282bcffc
Part II 仍然需要主節點的分散式架構 (比較簡單的架構,但尚未達到完全去中心化)
https://medium.com/@mycoralhealth/part-2-networking-code-your-own-blockchain-in-less-than-200-lines-of-go-17fe1dad46e1
工作證明
Code your own blockchain mining algorithm in Go
https://medium.com/@mycoralhealth/code-your-own-blockchain-mining-algorithm-in-go-82c6a71aba1f
了解如何使用IPFS通過區塊鏈存儲數據
Learn to securely share files on the blockchain with IPFS
編寫區塊鏈 P2P 網路
Code a simple P2P blockchain in Go英文原文:https://medium.com/@mycoralhealth/code-a-simple-p2p-blockchain-in-go-46662601f417
中文翻譯:https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/510718/
中文翻譯內的資源連結是失效的,需要到英文原文才能連結查看更多相關文件
p2p 協議概述:
https://blog.csdn.net/echoaiya/article/details/45887843
根据拓扑结构的关系可以将P2P研究分为四种形式:
中心化拓扑(Centralized Topology)、
全分布式非结构化拓扑(Decentralized Unstructured Topology)、
全分布式结构化拓扑(Decentralized Structured Topology, 也称为DHT网络)、
半分布式拓扑(Partially Decentralized Topology)。
(1)
中心化拓扑最大的优点是维护简单、发现效率高。缺点是与传统C/S结构类似,易造成单点故障。这是第一代P2P网络采用的结构模式,经典案例是著名的MP3共享软件Napster。
(2)
全分布非结构化网络在重叠网络采用了随机图的组织方式,结点度数服从“Power-law”规律,从而能够较快发现目的结点,面对网络的动态变化体现了较好的容错能力,因此具有较好的可用性。同时可以支持复杂查询,如带有规则表达式的多关键词查询,模糊查询等,最典型的案例是 Gnutella。
(因为此类网络采用了随机图、泛洪等机制,构建的系统没有固定的结构,故称为非结构化)
(随机图的“随机”二字体现在边的分布上。一个随机图实际上是将给定的顶点之间随机地连上边,参考网址:http://blog.csdn.net/foreverdengwei/article/details/7337429)
Gnutella 是一个P2P文件共享系统,它和 Napster 最大的区别在于 Gnutella 是纯粹的P2P系统,没有索引服务器,它采用了基于完全随机图的泛洪(Flooding)发现和随机转发(Random Walker)机制。为了控制搜索消息的传输,通过TTL(Time To Live)的减值来实现。详情参见 [Gnutella 协议]。
随着网络节点的不断增多,网络规模不断扩大,通过这种泛洪方式定位对等点的方法将造成网络流量急剧增加,从而导致网络中部分低带宽节点因网络资源过载而失效。所以在初期的Gnutella网络中,存在比较严重的分区、断链现象。也就是说,一个查询访问只能在网络的很小一部分进行,因此网络的可扩展性不好。所以,解决Gnutella网络的可扩展性对该网络的进一步发展至关重要。
(3)
全分布式结构化拓扑网络。目前研究的重点放在了如何有效地查找信息上,最新的成果都是基于DHT的分布式查找和路由算法。这些算法都避免了类似Napster的中央服务器,也不像Gnutella那样基于广播进行查找,而是通过分布式散列函数,将输入的关键字惟一映射到某个结点上,然后通过某些路由算法同该结点建立连接。
DHT类结构能够自适应结点的动态加入/退出,有着良好的可扩展性、鲁棒性、结点ID分配的均匀性和自组织能力。由于重叠网络采用了确定性拓扑结构,DHT可以提供精确的发现。只要目的节点存在于网站中,DHT总能发现它,发现的准确性得到了保证,最经典的案例是Tapestry,Chord,CAN和Pastry。
DHT类结构维护机制较为复杂,尤其是节点频繁加入/退出造成的网络波动会极大增加DHT的维护代价。
DHT仅支持精确关键词匹配查找,无法支持内容/语义等复杂查询。
(4)
半分布式结构吸取了中心化结构和全分布式非结构化拓扑的优点,选择性能较高(处理、存储、带宽等方面性能)的节点作为超级节点(SuperNodes, Hubs),在各个超级点上存储了系统中其他部分节点的信息,发现算法仅在超级节点之间转发,超级节点再将查询请求转发给适当的叶子节点。半分布式结构也是一个层次式结构,超级点之间构成一个高速转发层,超级点和所负责的普通节点构成若干层次。最典型的的案例是KaZaa。
半分布式结构的特点是性能、可扩展性较好;较容易管理,对超级节点依赖性大,易于受到攻击;容错性易受影响。
比较标准/拓扑结构
|
中心化拓扑
|
全分布式非结构化拓扑
|
全分布式结构化拓扑
|
半分布式拓扑
|
可扩展性
|
差
|
差
|
好
|
中
|
可靠性
|
差
|
好
|
好
|
中
|
可维护性
|
最好
|
最好
|
好
|
中
|
发现算法效率
|
最高
|
中
|
高
|
中
|
复杂查询
|
支持
|
支持
|
不支持
|
支持
|
https://murphymind.blogspot.com/2017/09/bitcoin.mechanics.html
在 Bitcoin 中,如何讓大家知道新的 transaction 發生了?
Bitcoin 採用的作法是 gossip process - 把消息通知自己知道的人,聽到的人再通知其他人,依此類推。
Bitcoin scripts
Bitcoin transaction 裡的 input "addresses" 及 output "addresses" 實際上是 scripts:
習慣上,input "addresses" 的 script 稱為 scriptSig,
output "addresses" 的 script 稱為 scriptPubKey。
因為在最簡單的情況下,output script 指定 public key,而 input script 指定 signature。
要驗證一筆 transaction 是否 valid,把 input script 及 output script 結合起來執行,如果沒有 error,就視為是一筆 valid transaction。
在 Bitcoin 中,如何讓大家知道新的 transaction 發生了?
Bitcoin 採用的作法是 gossip process - 把消息通知自己知道的人,聽到的人再通知其他人,依此類推。
Bitcoin scripts
習慣上,input "addresses" 的 script 稱為 scriptSig,
output "addresses" 的 script 稱為 scriptPubKey。
因為在最簡單的情況下,output script 指定 public key,而 input script 指定 signature。
要驗證一筆 transaction 是否 valid,把 input script 及 output script 結合起來執行,如果沒有 error,就視為是一筆 valid transaction。
更多參考資料:
精通比特幣:http://book.8btc.com/master_bitcoin
精通比特幣第二版:http://book.8btc.com/masterbitcoin2cn
比特幣改進提案:https://en.bitcoin.it/wiki/Category:BIP
從原理解析,探討密碼學、橢圓曲線的原理,以及程式碼的撰寫:https://yhheho.gitbooks.io/bitcoin/
Block Chain Basic Knowledge: https://developpaper.com/block-chain-basic-knowledge/
指標與位址的教程:http://edisonshih.pixnet.net/blog/post/27961535
大數 big.NewInt(), .Lsh() vs 一般數的 >>右移 <<左移 位運算符:https://play.golang.org/p/__ityUdxwlt
在 Go 裡面做大數運算:
https://studygolang.com/static/pkgdoc/pkg/math_big.htm
http://weijr-note.blogspot.com/2013/04/go.html
.Cmp 比较x和y的大小。x<y时返回-1;x>y时返回+1;否则返回0。
big.Int 是一个结构体(struct),相当于C++中的class,所以每次新建 big.Int 时可以用 x := new(big.Int), 返回一个指针。注意对 big.Int 的算术操作,要使用该對象的成員函數,比如說 Add()。
用 Golang 的 flag 套件 建置 CLI (Command line):https://21st.each1.net/2019/05/golang-flag-cli-command-line.html
bytes.Join 的用法:https://play.golang.org/p/sQOBBheA0Y5
Golang 的 Map:
https://www.cnblogs.com/igloo1986/p/3546337.html
https://blog.golang.org/go-maps-in-action
Golang: 合併 slice 的 append 方法
https://21st.each1.net/2019/06/golang-slice-append.html
Golang: base58 編碼 & 解碼
https://21st.each1.net/2019/06/golang-base58.html
使用 String() 方法來客製化字符串的輸出
https://21st.each1.net/2019/06/string.html
Golang 環境變量:https://21st.each1.net/2019/05/golang.html
時間格式處理:
https://www.jianshu.com/p/fe56edd8d30b
https://blog.csdn.net/skh2015java/article/details/70051512
google "源码分析 比特币"
google "源码分析 p2p"
google "源码分析 比特币 p2p"
google "源码分析 乙太坊 p2p"
google "源码分析 bt p2p"
google "p2p 协议"
利用go語言實現比特幣的一些中文教學
google 『比特幣 UTXO golang』
https://www.twblogs.net/a/5b80a1d42b71772165a8628c
https://shanma.pro/tutorial/57052.html
Why separate execution of unlocking and locking scripts (為什麼單獨執行解鎖和鎖定腳本):
https://bitcointalk.org/index.php?topic=5095376.msg49150302#msg49150302
https://github.com/bitcoinbook/bitcoinbook/blob/second_edition_print3_rc2/ch06.asciidoc#tx_script