bitcoin

// 启动

ui      CMyApp::OnInit()

ui          CMyApp::OnInit2()

db              CAddrDB::LoadAddresses()                        // 加载地址

db                  加载用户自定义的地址 CAddress from addr.txt

db                  再从 Berkeley DB addr.dat 中加载 CAddress

net                     AddAddress()                                // 添加地址

net                         拒绝不能路由的地址(内网地址被判定为不能路由) // CAddress::IsRoutable

net                         拒绝当前节点的地址           // 节点的地址 保存在 全局变量 addrLocalHost

net                         保存到 全局变量 mapAddresses 中, key 是 IP + Port

main            LoadBlockIndex                      // 加载区块

db                  CTxDB::LoadBlockIndex();    // key是"blockindex"+块hash

db                      从 BerkeleyDB 中加载 到 全局变量 mapBlockIndex 中

main                如果 mapBlockIndex 为 empty, 说明 刚刚启动主链(狭义的,局部的,极有可能会被推翻的), 发起一个交易(无效的),并打包这个创世区块

db              LoadWallet                      // 加载钱包

db                  CWalletDB::LoadWallet           // 以键值对方式存储,

                        name为地址本,       存入 mapAddressBook

                        tx:钱包交易CWalletTx,           存入 mapWallet

                        key:公钥私钥对,      存入 mapKeys, mapPubKeys

                        defaultkey:当前用户公私钥对信息           存入 keyUser

                        setting: 是否挖矿, 交易费用, 外部IP+端口

main            ReacceptWalletTransactions          // 将不在块中的钱包交易放入到对应的内存交易对象 mapTransactions中

                    CTxDB::ContainsTx       // key是"blockindex"+钱包交易hash

main                CWalletTx::AcceptWalletTransaction

                        CMerkleTx::AcceptTransaction

                            CTransaction::AcceptTransaction

                                存入 mapTransactions(用于保存未打包的交易)

ui          CMainFrame::show()

ui              CMainFrame::CMainFrame()

net         StartNode()

                创建 tcp 监听socket

                启动 ThreadIRCSeed                        // 聊天线程

                启动 ThreadSocketHandler              // socket监听线程

                启动 ThreadOpenConnections                // 连接其他node的线程

                启动 ThreadMessageHandler             // 消息处理线程

net         ThreadBitcoinMiner          // 启动挖矿线程






 

// 用于: 1:监听新进连接, 2: 处理vNode的 接收 和发送 缓冲区

ThreadSocketHandler

    LOOP{

        断开不使用的节点        

        accept 新连接(非阻塞), 存入 vNode

        循环处理所有节点的 recv buffer 和 send buffer

    }

    

 

// 用于不停的创建与其他节点的连接

ThreadOpenConnections

    LOOP{

        从 mapAddresses 加载所有地址, 排序分组

        随机创建连接 存入 vNode

    }

 

// 用于处理每一个节点上的消息, 与 ThreadSocketHandler 的分工是, 它处理消息逻辑, 会读取和写入 节点上的 recv buffer 和 send buffer, 而 由 ThreadSocketHandler 去完成 具体的 send 和 recv 函数调用

ThreadMessageHandler

    LOOP vNode{

        ProcessMessage 处理消息

            version: 消息的版本

            addr: 地址消息, 添加的本地地址簿中

            inv: 库存(交易, 区块, review, product)消息: CInv 中只有类型和内容hash, 该消息用于告知别人我有啥, 收到消息的node查看自己是否有, 如果没有就将请求放入 对方节点 的 mapAskFor 中, 在后续的 SendMessage 中处理

            getdata:    // 有人找我要Block数据, 直接掉对方 CNode::PushMessage("block") 等待发送

            getblocks:

            tx:             // 接受到了交易信息

            review:

            block:

            getaddr:

            checkorder:

            submitorder:

            reply:


 

        SendMessages 发送消息

            addr: 地址信息发送, 告诉别人我知道谁谁谁

            inventory:

            getdata: 遍历 节点 的 mapAskFor 发送 getdata 消息

 

    }

    

    

 

// 挖矿

ThreadBitcoinMiner

LOOP{

根据最高的Block(即上一个Block)计算出本次挖矿的难度值

新建一个BaseCoin交易

新建一个Block, append 刚刚的BaseCoin交易

收集最新的交易放入区块中

LOOP 本地交易池 mapTransactions

{

根据交易系列化大小计算fee

本次打包拒绝fee太低的交易

}

计算满足难度的hash值

处理Block ::ProcessBlock

}

 

// 自己挖到, 或接手到

// 处理Block

::ProcessBlock

判断重复

校验合法 CBlock::CheckBlock

判断高度, 发起缺失的block的请求 CNode::PushMessage("getblocks")

接受存储改Block CBlock::AcceptBlock

        RelayInventory          // 转播库存, 告知被人我有了这个 Block (消息中只有Block的hash)

            放入 每一个 vNode 的 vInventoryToSend, 等待 ThreadMessageHandler处理


 

递归处理依赖于此块的任何孤立块

 

// 转账, 注: 要求对方在线

CSendingDialog::StartTransfer()

判断余额

链接对方

向对方发送 checkorder 以询问对方是否接受交易并允许查看order内容

等待回复

CreateTransaction // 创建钱包交易

寻找自己的vOut

签名

CommitTransactionSpent // 提交交易

加入到钱包

标记 vOut 已经花掉了

CNode::PushRequest("submitorder") 确认一个order已经被提交

验证并接受交易, 存入 mapTransactions 中

 

ThreadRequestProductDetails



 

// 退出

ui      CMyApp::OnExit()

ui          ::Shutdown()

net             ::StopNode()

                    等待所有线程退出







 

// 打印 Block tree

db          CTxDB::LoadBlockIndex();

                从 db 中加载出 CBlockIndex, 组织成 <块哈希, CBlockIndex*> 存入全景变量 mapBlockIndex 中

main        PrintBlockTree();


 

// CBlockIndex 的 作用是 从本地的 blkxxxx.dat 文件中 索引出 CBlock 数据

    CBlock::ReadFromDisk

// CBlockIndex 是 存在 Berkeley DB 中的, 其数据文件 blkindex.dat

"sgmediation.zip" 是一个包含 UCLA(加利福尼亚大学洛杉矶分校)开发的 sgmediation 插件的压缩包。该插件专为统计分析软件 Stata 设计,用于进行中介效应分析。在社会科学、心理学、市场营销等领域,中介效应分析是一种关键的统计方法,它帮助研究人员探究变量之间的因果关系,尤其是中间变量如何影响因变量与自变量之间的关系。Stata 是一款广泛使用的统计分析软件,具备众多命令和用户编写的程序来拓展其功能,sgmediation 插件便是其中之一。它能让用户在 Stata 中轻松开展中介效应分析,无需编写复杂代码。 下载并解压 "sgmediation.zip" 后,需将解压得到的 "sgmediation" 文件移至 Stata 的 ado 目录结构中。ado(ado 目录并非“adolescent data organization”缩写,而是 Stata 的自定义命令存放目录)目录是 Stata 存放自定义命令的地方,应将文件放置于 "ado\base\s" 子目录下。这样,Stata 启动时会自动加载该目录下的所有 ado 文件,使 "sgmediation" 命令在 Stata 命令行中可用。 使用 sgmediation 插件的步骤如下:1. 安装插件:将解压后的 "sgmediation" 文件放入 Stata 的 ado 目录。如果 Stata 安装路径是 C:\Program Files\Stata\ado\base,则需将文件复制到 C:\Program Files\Stata\ado\base\s。2. 启动 Stata:打开 Stata,确保软件已更新至最新版本,以便识别新添加的 ado 文件。3. 加载插件:启动 Stata 后,在命令行输入 ado update sgmediation,以确保插件已加载并更新至最新版本。4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值