1990 年 8 月,Bellcore(1984 年由 AT&T 拆分而来的研究机构)的 Stuart Haber 和 W. Scott Stornetta 在论文《How to Time-Stamp a Digital Document》中就提出利用链式结构来解决防篡改问题,其中新生成的时间证明需要包括之前证明的 Hash 值。这可以被认为是区块链结构的最早雏形。
func(pool *ConnectionPool)NewConnection(conn net.Conn, solicited bool)(*Connection, error) { a := conn.RemoteAddr().String() var nc *Connection if err := pool.strand("NewConnection", func()error { if _, ok := pool.addresses[a]; ok { return fmt.Errorf("Already connected to %s", a) }
if _, ok := pool.Config.DefaultPeerConnections[a]; ok { iflen(pool.defaultPeerConnections) >= pool.Config.MaxDefaultPeerOutgoingConnections && solicited { return ErrMaxDefaultConnectionsReached }
for { elapser.CheckForDone() select { case <-pool.quit: returnnil case <-qc: returnnil case m := <-conn.WriteQueue: elapser.Register(fmt.Sprintf("conn.WriteQueue address=%s", conn.Addr())) if m == nil { continue }
err := sendMessage(conn.Conn, m, timeout)
if err == nil { if err := pool.updateLastSent(conn.Addr(), Now()); err != nil { logger.Warningf("updateLastSent(%s) failed", conn.Addr()) } }
sr := newSendResult(conn.Addr(), m, err) select { case <-qc: returnnil case pool.SendResults <- sr: default: logger.Warningf("SendResults queue full address=%s", conn.Addr()) }
// write data to buffer if _, err := conn.Buffer.Write(data); err != nil { return err } // decode data datas, err := decodeData(conn.Buffer, pool.Config.MaxMessageLength) if err != nil { return err } for _, d := range datas { select { case <-qc: returnnil case <-pool.quit: returnnil case msgChan <- d: default: return errors.New("readLoop msgChan is closed or full") } } sendInMsgChanElapser.CheckForDone() } }
case m := <-dm.messageEvents: elapser.Register("dm.messageEvents") if dm.Config.DisableNetworking { logger.Error("There should be no message events") returnnil } dm.processMessageEvent(m) ......
func(dm *Daemon)processMessageEvent(e MessageEvent) { if dm.needsIntro(e.Context.Addr) { _, isIntro := e.Message.(*IntroductionMessage) if !isIntro { dm.Pool.Pool.Disconnect(e.Context.Addr, ErrDisconnectNoIntroduction) } } e.Message.Process(dm) }
// Block represents the block struct type Block struct { Head BlockHeader Body BlockBody } // HashPair including current block hash and previous block hash. type HashPair struct { Hash cipher.SHA256 PreHash cipher.SHA256 }
// BlockHeader records the block header type BlockHeader struct { Version uint32
Time uint64 BkSeq uint64// Increment every block Fee uint64// Fee in block
PrevHash cipher.SHA256 // Hash of header of previous block BodyHash cipher.SHA256 // 默克尔树hash
UxHash cipher.SHA256 // XOR of sha256 of elements in unspent output set }
// BlockBody represents the block body type BlockBody struct { Transactions Transactions }
// SignedBlock signed block type SignedBlock struct { Block Sig cipher.Sig //cipher.SignHash(Block.HashHeader(), genSecret) 以上是Sig的由来 }
默克尔树的hash给予BodyHash
1 2 3 4 5 6 7 8 9 10
// Hash returns the merkle hash of contained transactions func(bb BlockBody)Hash()cipher.SHA256 { hashes := make([]cipher.SHA256, len(bb.Transactions)) for i := range bb.Transactions { hashes[i] = bb.Transactions[i].Hash() } // Merkle hash of transactions return cipher.Merkle(hashes) }
type Blockchain struct { db *dbutil.DB cfg BlockchainConfig store chainStore }
type chainStore interface { Head(*dbutil.Tx) (*coin.SignedBlock, error) HeadSeq(*dbutil.Tx) (uint64, bool, error) Len(*dbutil.Tx) (uint64, error) AddBlock(*dbutil.Tx, *coin.SignedBlock) error GetBlockByHash(*dbutil.Tx, cipher.SHA256) (*coin.Block, error) GetSignedBlockByHash(*dbutil.Tx, cipher.SHA256) (*coin.SignedBlock, error) GetSignedBlockBySeq(*dbutil.Tx, uint64) (*coin.SignedBlock, error) UnspentPool() blockdb.UnspentPool GetGenesisBlock(*dbutil.Tx) (*coin.SignedBlock, error) GetBlockSignature(*dbutil.Tx, *coin.Block) (cipher.Sig, bool, error) ForEachBlock(*dbutil.Tx, func(*coin.Block)error) error } // BlockchainConfigconfiguresBlockchainoptions typeBlockchainConfigstruct { // Arbitrating mode: if in arbitrating mode, when master node execute blocks, // the invalid transaction will be skipped and continue the next; otherwise, // node will throw the error and return. Arbitrating bool Pubkey cipher.PubKey }
交易事务相关 coin/transaction
交易结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// Transaction transaction struct type Transaction struct { Length uint32//length prefix Type uint8//transaction type InnerHash cipher.SHA256 //inner hash SHA256 of In[],Out[]
Sigs []cipher.Sig //list of signatures, 64+1 bytes each In []cipher.SHA256 //ouputs being spent Out []TransactionOutput //ouputs being created }
// TransactionOutput hash output/name is function of Hash type TransactionOutput struct { Address cipher.Address //address to send to Coins uint64//amount to be sent in coins Hours uint64//amount to be sent in coin hours 币时 }
关键方法
交易事务的Hash
1 2 3 4 5
// Hash an entire Transaction struct, including the TransactionHeader func(txn *Transaction)Hash()cipher.SHA256 { b := txn.Serialize() return cipher.SumSHA256(b) }
获取交易长度
1 2 3 4
// Size returns the encoded byte size of the transaction func(txn *Transaction)Size()int { returnlen(txn.Serialize()) }
//Unspent Outputs // UxOut represents uxout type UxOut struct { Head UxHead Body UxBody //hashed part //Meta UxMeta }
// UxHead metadata (not hashed) type UxHead struct { Time uint64//time of block it was created in BkSeq uint64//block it was created in, used to calculate depth // SpSeq uint64 //block it was spent in }
// UxBody uxbody type UxBody struct { SrcTransaction cipher.SHA256 // Inner Hash of Transaction Address cipher.Address // Address of receiver Coins uint64// Number of coins Hours uint64// Coin hours }
Address地址 cipher/address
正常情况用户地址生成过程
1 2 3 4 5
通过传入的seed生成私钥 ⇣ 通过传入私钥生成公钥 ⇣ 通过传入公钥生成地址
当然address也可以直接从私钥上产生或者直接一些byte数组上产生
AddressFromSecKey
AddressFromPubKey
AddressFromBytes
基本结构
1 2 3 4 5 6 7
// Address version is after Key to enable better vanity address generation // Address stuct is a 25 byte with a 20 byte publickey hash, 1 byte address // type and 4 byte checksum. type Address struct { Version byte//1 byte Key Ripemd160 //20 byte pubkey hash }
// The wallet can create transactions that would not pass all validation, such as the decimal restriction // because the wallet is not aware of visor-level constraints. // Check that the transaction is valid before returning it to the caller. err = gw.v.VerifySingleTxnAllConstraints(txn)
type Transaction struct { Length uint32//length prefix Type uint8//transaction type InnerHash cipher.SHA256 //inner hash SHA256 of In[],Out[]
Sigs []cipher.Sig //list of signatures, 64+1 bytes each In []cipher.SHA256 //ouputs being spent Out []TransactionOutput //ouputs being created }
// UxOut represents uxout type UxOut struct { Head UxHead Body UxBody //hashed part //Meta UxMeta }
// UxHead metadata (not hashed) type UxHead struct { Time uint64//time of block it was created in BkSeq uint64//block it was created in, used to calculate depth // SpSeq uint64 //block it was spent in }
// UxBody uxbody type UxBody struct { SrcTransaction cipher.SHA256 // Inner Hash of Transaction Address cipher.Address // Address of receiver Coins uint64// Number of coins Hours uint64// Coin hours }
//拿取Transaction.In for _, v := range Transaction.In{ unspent.Get(v) ....... }
// Transaction transaction struct type Transaction struct { Length uint32//length prefix Type uint8//transaction type InnerHash cipher.SHA256 //inner hash SHA256 of In[],Out[]
Sigs []cipher.Sig //list of signatures, 64+1 bytes each In []cipher.SHA256 //ouputs being spent Out []TransactionOutput //ouputs being created }
// TransactionOutput hash output/name is function of Hash type TransactionOutput struct { Address cipher.Address //address to send to Coins uint64//amount to be sent in coins Hours uint64//amount to be sent in coin hours }
// BroadcastMessage sends a Message to all connections in the Pool. func(pool *ConnectionPool)BroadcastMessage(msg Message)error { if pool.Config.DebugPrint { logger.Debugf("Broadcast, Msg Type: %s", reflect.TypeOf(msg)) }
fullWriteQueue := []string{} if err := pool.strand("BroadcastMessage", func()error { iflen(pool.pool) == 0 { return errors.New("Connection pool is empty") }
for _, conn := range pool.pool { select { case conn.WriteQueue <- msg: default: logger.Critical().Infof("Write queue full for address %s", conn.Addr()) fullWriteQueue = append(fullWriteQueue, conn.Addr()) } }
// UnconfirmedTxn unconfirmed transaction type UnconfirmedTxn struct { Txn coin.Transaction //交易结构 // Time the txn was last received 上一次接收时间 Received int64 // Time the txn was last checked against the blockchain 检查时间 Checked int64 // Last time we announced this txn 广播时间 Announced int64 // If this txn is valid 是否验证 IsValid int8 }
type Peer struct { Addr string// An address of the form ip:port LastSeen int64// Unix timestamp when this peer was last seen Private bool// Whether it should omitted from public requests Trusted bool// Whether this peer is trusted HasIncomingPort bool// Whether this peer has accessable public port RetryTimes int`json:"-"`// records the retry times }
func(dm *Daemon)connectToTrustPeer() { if dm.Config.DisableIncomingConnections { return }
logger.Info("Connect to trusted peers") // Make connections to all trusted peers peers := dm.Pex.TrustedPublic() for _, p := range peers { dm.connectToPeer(p) } }
--ethash.cachedir ethash验证缓存目录(默认 = datadir目录内) --ethash.cachesinmem value 在内存保存的最近的ethash缓存个数 (每个缓存16MB ) (默认: 2) --ethash.cachesondisk value 在磁盘保存的最近的ethash缓存个数 (每个缓存16MB) (默认: 3) --ethash.dagdir "" 存ethash DAGs目录 (默认 = 用户hom目录) --ethash.dagsinmem value 在内存保存的最近的ethash DAGs 个数 (每个1GB以上) (默认: 1) --ethash.dagsondisk value 在磁盘保存的最近的ethash DAGs 个数 (每个1GB以上) (默认: 2)
--txpool.nolocals 为本地提交交易禁用价格豁免 --txpool.journal value 本地交易的磁盘日志:用于节点重启 (默认: "transactions.rlp") --txpool.rejournal value 重新生成本地交易日志的时间间隔 (默认: 1小时) --txpool.pricelimit value 加入交易池的最小的gas价格限制(默认: 1) --txpool.pricebump value 价格波动百分比(相对之前已有交易) (默认: 10) --txpool.accountslots value 每个帐户保证可执行的最少交易槽数量 (默认: 16) --txpool.globalslots value 所有帐户可执行的最大交易槽数量 (默认: 4096) --txpool.accountqueue value 每个帐户允许的最多非可执行交易槽数量 (默认: 64) --txpool.globalqueue value 所有帐户非可执行交易最大槽数量 (默认: 1024) --txpool.lifetime value 非可执行交易最大入队时间(默认: 3小时)
//性能调优的选项 --cache value 分配给内部缓存的内存MB数量,缓存值(最低16 mb /数据库强制要求)(默认:128) --trie-cache-gens value 保持在内存中产生的trie node数量(默认:120)
//帐户选项 --unlock value 需解锁账户用逗号分隔 --password value 用于非交互式密码输入的密码文件
//API和控制台选项 --rpc 启用HTTP-RPC服务器 --rpcaddr value HTTP-RPC服务器接口地址(默认值:“localhost”) --rpcport value HTTP-RPC服务器监听端口(默认值:8545) --rpcapi value 基于HTTP-RPC接口提供的API(默认值:“eth,net,web3”) --ws 启用WS-RPC服务器 --wsaddr value WS-RPC服务器监听接口地址(默认值:“localhost”) --wsport value WS-RPC服务器监听端口(默认值:8546) --wsapi value 基于WS-RPC的接口提供的API --wsorigins value websockets请求允许的源 --ipcdisable 禁用IPC-RPC服务器 --ipcpath 包含在datadir里的IPC socket/pipe文件名(转义过的显式路径) --rpccorsdomain value 允许跨域请求的域名列表(逗号分隔)(浏览器强制) --jspath loadScript JavaScript加载脚本的根路径(默认值:“.”) --exec value 执行JavaScript语句(只能结合console/attach使用) --preload value 预加载到控制台的JavaScript文件列表(逗号分隔)
//网络选项 --bootnodes value 用于P2P发现引导的enode urls(逗号分隔)(对于light servers用v4+v5代替) --bootnodesv4 value 用于P2P v4发现引导的enode urls(逗号分隔) (light server, 全节点) --bootnodesv5 value 用于P2P v5发现引导的enode urls(逗号分隔) (light server, 轻节点) --port value 网卡监听端口(默认值:30303) --maxpeers value 最大的网络节点数量(如果设置为0,网络将被禁用)(默认值:25) --maxpendpeers value 最大尝试连接的数量(如果设置为0,则将使用默认值)(默认值:0) --nat value NAT端口映射机制 (any|none|upnp|pmp|extip:<IP>) (默认: “any”) --nodiscover 禁用节点发现机制(手动添加节点) --v5disc 启用实验性的RLPx V5(Topic发现)机制 --nodekey value P2P节点密钥文件 --nodekeyhex value 十六进制的P2P节点密钥(用于测试)
//矿工选项 --mine 打开挖矿 --minerthreads value 挖矿使用的CPU线程数量(默认值:8) --etherbase value 挖矿奖励地址(默认=第一个创建的帐户)(默认值:“0”) --targetgaslimit value 目标gas限制:设置最低gas限制(低于这个不会被挖) (默认值:“4712388”) --gasprice value 挖矿接受交易的最低gas价格 --extradata value 矿工设置的额外块数据(默认=client version)
//GAS价格选项 --gpoblocks value 用于检查gas价格的最近块的个数 (默认: 10) --gpopercentile value 建议gas价参考最近交易的gas价的百分位数,(默认: 50)
//日志和调试选项 --metrics 启用metrics收集和报告 --fakepow 禁用proof-of-work验证 --verbosity value 日志详细度:0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 3) --vmodule value 每个模块详细度:以 <pattern>=<level>的逗号分隔列表 (比如 eth/*=6,p2p=5) --backtrace value 请求特定日志记录堆栈跟踪 (比如 “block.go:271”) --debug 突出显示调用位置日志(文件名及行号) --pprof 启用pprof HTTP服务器 --pprofaddr value pprof HTTP服务器监听接口(默认值:127.0.0.1) --pprofport value pprof HTTP服务器监听端口(默认值:6060) --memprofilerate value 按指定频率打开memory profiling (默认:524288) --blockprofilerate value 按指定频率打开block profiling (默认值:0) --cpuprofile value 将CPU profile写入指定文件 --trace value 将execution trace写入指定文件
国内查看评论需要代理~