主页 > imtoken钱包苹果版手机下载 > 比特币是如何产生的?

比特币是如何产生的?

一些小准备

做比特币,我们需要了解比特币的一些基本规律(初始规则)。

比特币由区块链驱动。

区块是一个包含各种数据的存在,链接遍布整个比特币网络,所以每个人都有相同的数据源;让大家直接交易,每个账户的余额,真实的数据来源,完全统一,没有区别。

每个区块都以加密方式链接到前一个区块,从而形成一条很长的区块链,但每个区块都有新数据和新交易。

每个区块都包含交易,这意味着比特币可以在网络上不同的交易者之间转移,Keke给了Kevin 10个币,Kevin给了张若年5个币,以此类推,我们可以通过以下方式跟踪账户余额和交易记录查看所有历史区块。

有了“挖矿”,就有了“区块”。 “挖矿”过程需要一定的算力和运气,涉及的算力可能会成倍增长,这样的规则可以有效保护网络。

任何挖出一个区块的人都将获得固定数量的比特币奖励,这会鼓励矿工继续挖矿。

用户之间的交易也会产生费用,由区块矿工和区块奖励一起收取,因此挖掘新区块具有双重动机。

随着时间的推移,挖掘区块会变得困难或容易。这是为了保证新区块的挖矿速度在一个大概的水平上是恒定的,这样网络就不会受到挖矿时间的影响。使用时间过长,由于挖矿时间太短,不会很快受到影响。

网络上的每个节点都使用相同的规则集和块格式,这使得即使具有巨大的计算能力,也很难创建假块或创建重复的交易记录进行作弊。一点点。

了解了基本规律后,我们就开始圈一个库研究,先让一些代码跑起来。

export type TransactionType = {|
sender : string,
receiver : string,
amount : number,
fee : number
|};
export type BlockType = {|
miner : string,
parentid : string,
id : string,
index : number,
time : number,
elapsed : number,
transactions : Array,
difficulty : number,
reward : number
|};

这里有两点需要注意:

Blocks 下的字段是:

接下来是定义常数时间的时候了,我的最爱。

export const BLOCK_TIME = 1000;
export const INITIAL_REWARD = 1024;
export const REWARD_HALVING_SCHEDULE = 20;
export const BLOCK_SIZE_LIMIT = 10;
export const GENESIS_BLOCK : BlockType = {
id:           'GENESIS',
parentid:     'GENESIS',
miner:        'SATOSHI',
index:        1,
time:         now(),
elapsed:      0,
transactions: [],
difficulty:   1,
reward:       INITIAL_REWARD
};

定义好常量之后,让我们注意这些重要的参数:

BLOCK_TIME 是生成每个区块之间的目标时间,比特币每个区块之间有 10 分钟;我们这里只跑了 1 秒,在本地快速运行和试用。

INITIAL_REWARD 是每个区块的比特币奖励,奖励给任何挖掘该区块的人;随着时间的推移,奖励将减半,并鼓励更多矿工通过尝试区块、处理交易来挖掘区块,以保护网络免受其他类型的安全攻击。

REWARD_HALVING_SCHEDULE 是奖励减半之前的区块数。比特币通常每四年减半。我们这里设置为 20 块,相当于每 20 秒减半。

BLOCK_SIZE_LIMIT 是任何区块可以包含的最大交易限额,比特币的实际限额很高,但我们这里只设置为10。

GENESIS_BLOCK 定义了初始硬编码区块,所有其他区块都以此创世区块为祖先,我们将暂时授予此区块SATOSHI,并定义默认难度和初始区块奖励。

当我们在代码中键入这些参数时,它们的含义会越来越深刻,功能方向也会逐渐清晰。

这还没有结束,我们还需要将区块链作为“数据库”并记录我们所有的区块和交易的系统。

export type BlockChainType = {|
addBlock : (hashedBlock : string) => Promise,
createBlock : (publicKey : string, transactions : Array) => Promise,
getBalances : () => Promise
|};
export function BlockChain() : BlockChainType {
const createBlock = async (publicKey, transactions) : Promise => {
};
const addBlock = async (block : BlockType) => {
};
const getBalances = async () : Promise => {
};
return {
addBlock,
createBlock,
getBalances
};
}

好了,结构搭建好了,我们可以开始做事了!

我挖的不是矿,而是未来

来吧,我们先从它自己的数据结构说起:

const root = TreeNode(GENESIS_BLOCK);

对于区块链的构建,可能有同学认为会处于链表的状态。在实际结构中,区块链其实更像是一棵“区块树”。

好啦~有图为证

在这个块树中,可以有很多相互竞争的分支,我们如何选择和信任?

EASY,三短一长,选最长的,这道题我就知道了!

真的,我们选择哪个分支最长,因为更长的分支意味着可以创建更多的计算工作,而更多的计算工作确保没有其他分支可以超过我们当前的选择。

所以我们使用数据结构来表示内存中的区块链,以便轻松计算任何给定时间的最长分支。注意这里我们传入 GENESIS_BLOCK 作为块树的根,因为它总是第一个块。

好的,一切都准备好了,就我的,我的!

const createBlock = async (publicKey : string, transactions : Array) : Promise => {
const headBlock = root.getLongestBranchNode().getValue();
const newTransactions = await asyncFilter(transactions, verifyPackedSignature);
const newDifficulty = (headBlock.elapsed) > BLOCK_TIME
? headBlock.difficulty - 1
: headBlock.difficulty + 1;
const newReward = divisibleBy(headBlock.index, REWARD_HALVING_SCHEDULE)
? Math.floor(headBlock.reward / 2)
: headBlock.reward;
const newBlock = {
miner:        publicKey,
parentid:     headBlock.id,
index:        headBlock.index + 1,
id:           uniqueID(),
time:         now(),
elapsed:      now() - headBlock.time,
transactions: newTransactions,
difficulty:   newDifficulty,
reward:       newReward
};
const hashedBlock = await hashAndPack(newBlock);
const hash = unpackHash(hashedBlock);
if (divisibleBy(hash, headBlock.difficulty)) {
return hashedBlock;
}
};

以上代码是挖掘新矿的过程。锄头再用力,也要注意落地的力度。在挖矿过程中,我们需要注意三个步骤:

现有区块链,这里表示为root,我们需要在这里调用getLongestBranchNode() 来找到当前“真实”的区块链并在其上挖掘另一个块。

矿工的公钥,它需要是区块的一部分,以便网络上的其他人都知道挖掘区块的奖励信息。

交易列表,如果没有交易记录可以在网络上发布,挖矿将毫无意义。

矿可以挖到了,交易记录没问题,还需要担心什么?

A:我担心奖励系统的设置。

我们希望每20个区块奖励减半,所以这里我们使用选择判断的方法:

如果出块时间过长,我们将难度降低1。

如果出块时间太短,我们将难度增加1。

这意味着每个区块的创建过程都会被算法根据前一个区块所花费的时间进行调整,从而导致整体的区块发现率接近一个常数。

无论有多少矿工尝试挖掘新区块,新区块的发现率始终保持在恒定范围内。

你拥有的矿工越多,“哈希率”就越高,这也是衡量世界各个地区目前使用多少计算能力来挖掘比特币的指标。这又会导致两个结果:

矿工数量少,算力低,难度低。矿工数量多,算力高,难度高。

当我们成功创建一个新区块时,任务还没有结束,我们需要根据前一个区块确定标准,当对应的难度正确时,我们创建的新区块将被网络接受。

包是安全的,包是安全的

新块创建成功后,我们需要将它添加到我们的数据结构中。

const addBlock = async (hashedBlock : string) => {
const verifiedBlock = await verifyHashAndUnpack(hashedBlock);
const verifiedTransactions = await asyncMap(verifiedBlock.transactions, verifySignatureAndUnpack);
const fullyVerifiedBlock = {
...verifiedBlock,
transactions: verifiedTransactions
};
const headNode = root.findValueByID(fullyVerifiedBlock.parentid);
const hash = unpackHash(hashedBlock);
if (headNode && divisibleBy(hash, headNode.getValue().difficulty)) {
headNode.addChildNodeValue(fullyVerifiedBlock);
}
};

第一步是验证新区块是否与哈希匹配,并且该区块内的所有交易均已正确签名;然后验证新块是否通过了所有正确的规则;最后,我们需要找到新区块指定的父区块比特币的总量是怎么定下来的,并将新区块添加为父区块下的子节点比特币的总量是怎么定下来的,宾果,访问工作完成!

连接后,就是计算余额的时间了,这是投机者的最爱(毕竟落入口袋是安全的)。

const getBalances = async () : Promise => {
const balances = new Counter();
for (let { miner, reward, transactions } of root.getLongestChainAsValues()) {
balances.add(miner, reward);
for (let { receiver, amount, fee, sender } of transactions) {
balances.add(miner, fee);
balances.add(receiver, amount);
balances.subtract(sender, amount);
balances.subtract(sender, fee);
}
}
return balances;
};

在最长的分支链下,我们将所有余额、费用和区块奖励相加,并计算以下每个选项:

p>

矿工每获得一个区块奖励。

矿工每笔交易都会收取费用。

收款人获得交易金额。

发件人丢失了交易金额。

发件人损失交易费。

好了,到这里,一个简单的比特币就生成了!

你有没有发现一个亮点,比特币交易实际上是一场零和游戏。金额从一个帐户中减去并添加到另一个帐户。所有交易只能使用网络上已经存在的比特币,而比特币不能被创建或销毁。 (当然,你可以将比特币发送到死地址,但这不会破坏比特币,它只会使比特币的那部分永久无法访问。)

虽然交易是零和的,但奖励不是。

从生成新区块到最终获得比特币奖励,这个渠道是当前所有新比特币的来源。但这个奖励也有一个应许的结局。我们说比特币的上限很高,这个固定值是2100万,当最终区块奖励减半为0时,系统将无法增减新的比特币。

这个固定的上限赋予比特币巨大的 S2F(资产稀缺性)价值。挖矿币最终会用完,永远不会有中央银行发行。额外的货币会造成通货膨胀危机。

因此,你在新闻网站上看到的各种公司或个人都投入了大量资金进行挖矿,而电商平台的显卡则供不应求,被囤积起来挖矿。所有这些人都在追求新的采矿。承诺的比特币奖励。

引人入胜的数据操作很有趣,精确的逻辑计算引人入胜,比特币创造了伟大的经济奇迹(从0元/块到高达6万美元/块,没有实物作为支撑) .

今天我们介绍如何使用JAVA简单重构比特币的生成过程(创建新区块到最终计算访问区块链的余额),希望热爱计算机知识的你满意。

像近两年层出不穷的虚拟货币(Dogecoin、Huobi、OMG Coin)一样,拥有先进的计算机知识,你也可以参与新币的发行和交易。

比特币这么火,你怎么不也发一个?

参考链接:

比特币是如何运作的?