转账、确认与手续费
一笔钱如何到账,为什么要等确认,何时需要手续费。
按议题整理 · 中文阅读 · 68 条发言。英文及完整讨论可回到对应档案查看。
到账、确认与交易重新广播
13 条
那更多是 SelectCoins 层面的事。
那更多是 SelectCoins 层面的事。
SVN rev 161 有一个改进:递归判断你自己的未确认交易能否被花费。这是必需的,因你应该能立刻花掉自己的找零。
新的递归判定是:0/unconfirmed 能花费,条件是它是你的,而且它的所有依赖要么已进区块、要么也是你的。
这是一个 Windows 构建:
http://www.bitcoin.org/download/bitcoin-0.3.13.2-win32-setup.exe
如果你已经有 0/unconfirmed 交易、而且可能已经花过它,这个版本是个改进。如果你是某笔 0/unconfirmed 交易的原始创建者,你仍然需要用 theymos 的补丁。
确保你的节点保持在线,这样它才能持续重播交易 b412a0。从 29/09/2010 16:41 起就未见它重播过了。
在你的节点拥有一条回溯到区块链的交易路径之前,交易不会被接受、也不会显示为 0/unconfirmed。
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
其他参与者原话theymos原帖 ↗ArtForz 已经在免手续费运行了,他占全网算力的 20-30%。不过,最初发送这些坏交易的人已经删掉了自己的钱包,网络也忘掉了这些历史交易,因此基于此的交易无法确认。
在你的节点拥有一条回溯到区块链的交易路径之前,交易不会被接受、也不会显示为 0/unconfirmed。
你钱包里的任何交易也都捆绑着回溯到区块链所需的全部尚未上链的交易。如果你有一笔显示为 0/unconfirmed 的交易,那么它依赖的所有先前尚未上链的交易你都有,你重播自己的交易时也会一并重播它们。
如果免手续费的区块已经生成、却没起作用,那我需要看看哪里出了问题。这是一段很少被用到的代码。只要某人的钱包中有交易依赖这些前序交易,这些前序交易就应该也保存在他的钱包中。
其他参与者原话theymos原帖 ↗最初发送这些坏交易的人已经删掉了自己的钱包
叹气……为什么要删除钱包,而不是把它移到一边、留个旧副本以防万一?永远不要删除钱包。
其他参与者原话tcatm原帖 ↗已经在跑了。3 小时内应该能出一个块。
收集重新广播的交易可能需要一段时间。如果你能接受入站连接会更有帮助,这样就能收到更多节点的消息。就算你 3 小时内出了块,也请至少连续跑上几天。
正如你想明白的那样,根本问题在于:交易获得至少 1 个确认之前,我们不该把它计入余额,也不该花费这笔钱。0/unconfir…
正如你想明白的那样,根本问题在于:交易获得至少 1 个确认之前,我们不该把它计入余额,也不该花费这笔钱。0/unconfirmed 交易就是彻头彻尾的二等公民。它们至多是「收到了什么东西」的提示,把它们计入余额或花出去都为时过早。
我做了改动,让它们以浅色显示,金额放在方括号里如 [+1.23],不计入余额、不可用于花费。这并不适用于你发出的交易——你默认信任它们,因为是你自己创建的。
我并未用 (+1.23),因会计里圆括号表示负数。我希望方括号与圆括号有足够明显的区别,让人明白它的含义。
如果需要,仍可在 JSON-RPC 接口中指定 0 个确认,查看 0/unconfirmed 交易。
我已把改动上传到 SVN rev 158。我很快会发 0.3.13 RC。
如果你的钱包里有这类交易,在升级到 0.3.13(很快会来)之前,不要发出任何支付。
如果你已经发出过这类交易,或者你就是它们的创建者,那么用 theymos 的补丁,或者做下面这个改动,然后用它把你的干净交易发到一个新钱包,清理干净。
把:
if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0)
continue;
改成:
if (pcoin->GetDepthInMainChain() < 1)
continue;
没错。即使你不重新广播自己的交易,这个机制也能正常运作。
没错。即使你不重新广播自己的交易,这个机制也能正常运作。
当任何节点断开一个分叉时,它会把分叉里的全部交易倒回交易池,以便加入新链。整个网络都在保证把你的交易重新整合进去。你唯一会看到的就是确认数从 0 重新开始计数。
在某些类型的分叉里,你的交易本来就已经进了两条分叉,所以无论哪边赢你都没事。
如果交易一开始没有立刻发出去,比如你当时没连网,重发最长可能要等 2 小时。长期来看,它确实会锲而不舍地一直发。
如果交易一开始没有立刻发出去,比如你当时没连网,重发最长可能要等 2 小时。长期来看,它确实会锲而不舍地一直发。
未来版本我会把这个时长缩短。
你得先下载完整的区块链(当前 71040 个区块)才能看到任何确认。收款方也一样。
我没说滴水不漏,我说的是足够好。实际操作中的损失会远低于信用卡。
我相信支付处理公司可以把「快速分发交易 + 足够好的校验」作为一种服务提供,在大约 10 秒或更短时间内完成。
我相信支付处理公司可以把「快速分发交易 + 足够好的校验」作为一种服务提供,在大约 10 秒或更短时间内完成。
网络节点只接受收到的第一版交易,纳入它正在尝试生成的区块。当你广播一笔交易时,如果别人同时广播了一笔双重支付,这就是一场看谁先传播到最多节点的竞赛。谁有一点先发优势,就会以几何级数在网络上扩散得更快,拿下大多数节点。
粗略的估算例子:
1 0
4 1
16 4
64 16
80% 20%
所以双重支付哪怕只晚一秒,都处于巨大劣势。
支付处理服务商会与许多节点保持连接。收到一笔交易后,它会立刻向外广播,同时监控网络中是否出现双重支付。只要它连接的任一监听节点收到冲突交易,支付处理服务商就会把原交易标记为有问题。双重支付交易很难广泛传播而不被其中一个节点发现。攻击者必须等监听阶段结束后再行动,可到那时,支付处理服务商广播的交易已经到达大多数节点,或者在传播速度上遥遥领先,攻击者几乎不可能再争取到足够多的剩余节点。
如果客户端收到的新区块里没有你的交易,Bitcoin 会自动重播它。重播大约要一个小时。不过它是不屈不挠的。它会永远不厌其烦…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
如果客户端收到的新区块里没有你的交易,Bitcoin 会自动重播它。重播大约要一个小时。不过它是不屈不挠的。它会永远不厌其烦地骚扰网络,直到你的交易进了区块。
按 IP 地址发送是即时的。按比特币地址发送而收款方当时不在线的话,可能要过 30 分钟以上才能看到。
按 IP 地址发送是即时的。按比特币地址发送而收款方当时不在线的话,可能要过 30 分钟以上才能看到。
另外,收款方要先与区块链同步才能看到收到的交易。也就是说底部状态栏至少要显示 33000 区块,比如 "x connections 33200 blocks x transactions"。
其他参与者原话sirius-m原帖 ↗一笔交易的区块数,指的是这笔交易之后,整个网络生成的新区块数量。链上每个新区块,都意味着新比特币归其创建者。你交易列表里的一条 "generated" 交易,表示的就是你生成了一个区块。"区块"这个概念,第一眼看不明白,你并非第一个。
如果状态显示 "x confirmations" 会不会更清楚,比如:
2/unconfirmed
3/unconfirmed
4/unconfirmed
5/unconfirmed
6 confirmations
7 confirmations
8 confirmations
每个区块实质上意味着又一个节点确认了它认同截至该处为止的全部交易。
对。我正在想更清楚的表述,也许用“%d 个网络区块”或者“%d 个区块的链”。
阅读完整通信正文 · Mike Hearn · 2009-04-13 · 首次试用、微支付与工作量证明
谢谢,Satoshi,
我昨天试了这个应用。通过 Wine 运行时似乎表现相当不错(我在 MacOS 上试的,不过它应该也能在 Linux 上运行;下周回去上班时,我会再试)。
右下角有一个区块计数,会迅速增加,然后停下来。这是全局链的长度吗?如果是,它增加得似乎太快了。还是说,这是尝试过、却没有找到部分碰撞的创世区块数量?我不确定,这种时停时走是正常现象,还是通过模拟环境运行造成的故障。我觉得最有可能的解释是:它表示全局链的长度,刚开始迅速增加,是因为软件正在下载链上之前的区块,并验证它们是否有效。
关于买卖双方的使用体验,我理解按当前设置,全局链每小时大约增加 6 至 7 个区块。如果假定 0.1% 是个可以接受的风险,那么 z=5,因此一笔交易必须等待接近一小时,才能在链中稳固下来。网页内容、虚拟商品等微支付,本来就要求很低的额外成本;等待一小时似乎是个相当大的障碍。
我理解,各节点会在没有协调的情况下尝试寻找工作量证明,来延长全局链。不过,下面这句话:
引用白皮书Satoshi Nakamoto来源 ↗“如果大多数 CPU 算力由诚实节点控制,诚实链就会增长得最快,并超过任何竞争链。”
让我感到困惑。因为在我看来,诚实链要比攻击者用一个 CPU 维护的链增长得更快,唯一的办法似乎是:把寻找部分碰撞时需要扫描的密钥空间,平均分配给参与的诚实节点。这样,找到碰撞的速度才会与节点数量成正比。但我没有看到任何关于这种工作划分的讨论,而它显然会增加复杂度。类似地:
引用白皮书Satoshi Nakamoto来源 ↗“为了应对硬件速度的提高,以及人们运行节点的意愿随时间变化,工作量证明的难度由移动平均确定,目标是每小时平均生成一定数量的区块。如果生成得太快,难度就会提高。”
每个区块所需的难度,是怎样在网络中传达并达成一致的?
再次感谢。我还有更多问题,不过一封邮件问这些已经够多了 :) 找个时候,我很乐意把这些讨论整理成类似常见问题的文档。如果这些问题显得太基础,还请见谅。
—mike
引用的来信Mike Hearn来源 ↗我觉得最有可能的解释是:这是全局链的长度,而开始时快速增长,是因为软件正在下载并验证链中已有的区块是否有效。
对。我正在想更清楚的表述,也许用“%d 个网络区块”或者“%d 个区块的链”。
引用的来信Mike Hearn来源 ↗如果我们认为 0.1% 是可以接受的风险率,那么 z=5,因此任何交易都必须等待将近一小时,才能在链中确定下来。用于网页内容或虚拟商品等的微支付,顾名思义就需要很低的额外负担,等一小时似乎是个相当大的障碍。
计算实际风险时,要把 0.1% 乘以买家是一个拥有庞大计算机网络的攻击者的概率。
对于微支付,你可以安全地立即接受付款。金额太小,不值得费力去偷。微支付几乎总是用来购买知识产品,商家不会有实物损失。试图通过微支付逃单的人,无论如何大概都不会成为付费客户;而且,如果他们想盗取这些知识产品,可以使用文件共享网络。
目前,商家会接受一定比例的坏账。我相信,即使只有 1 个、甚至 0 个确认区块,风险也会远低于已验证信用卡交易的拒付率。
对不等待确认区块的商家,常见的骗局会是先向商家付款,然后赶在商家的交易副本之前,迅速尝试向网络传播一笔双重支付。商家可以广播自己的交易,再监测网络中是否出现任何双重支付副本。窃贼无法在监测期间广播,否则商家的节点就会收到副本。商家只需监测一两分钟,直到大多数网络节点拥有自己的版本,而窃贼的版本已经来不及追上并传遍大量节点。只延迟一两分钟,就能把不付款而得手的概率降到不值得行骗的程度。窃贼通常需要很高的概率免费拿到商品,才值得做。除了上述骗局,再投入大量 CPU 算力进行论文中讨论的暴力攻击,也不会显著增加窃贼的胜算。
凡是授予某种访问权限的东西,例如需要一段时间才能下载的内容、网站访问、虚拟主机、订阅或服务,都可以在几分钟后交易被拒绝时取消。
引用的来信Mike Hearn来源 ↗这一点让我困惑,因为看起来,诚实链要比攻击者用 1 个 CPU 计算的链增长得更快,唯一办法就是把寻找部分碰撞需要扫描的搜索空间,均匀划分给参与的诚实节点。这样,找到碰撞的速度才会与节点数量成正比。但我没看到任何关于这种任务划分的讨论,而这显然会增加复杂性。
搜索空间非常大,有 2^256。被哈希的内容包含节点的公钥和一个随机 nonce,所以任意两个节点在同一空间重复计算的概率可以忽略不计。
引用的来信Mike Hearn来源 ↗每个区块所要求的难度,是如何在网络中传播并达成一致的?
它不需要传播。公式硬编码在程序里,每个节点都进行相同的计算,从而知道下一个区块要求的难度。如果有人偏离公式,他的区块就不会被大多数节点接受。
引用的来信Mike Hearn来源 ↗再次感谢。我还有更多问题,不过一封邮件写这些就够了 :) 我很乐意在某个时候把这些讨论整理成类似常见问题解答的文档。如果这些问题显得太浅显,抱歉。
没问题,谢谢你在 Mac Wine 上测试。
Satoshi
Ray Dillinger 写道:
Ray Dillinger 写道:
引用的来信Ray Dillinger来源 ↗一种做法是让收币的人生成一对非对称密钥,然后将其中一半随交易公布。为了以后花掉这个币,他或她必须证明自己持有这对非对称密钥的另一半,可能是用它为新卖方提供的密钥签名。
对,使用的是 ECC 数字签名。每笔交易都使用一对新密钥。
它并不通过假名来识别使用者,但仍有一定的假名性:人们可以认定,对某个币的下一次操作来自这个币的所有者。
引用的来信Ray Dillinger来源 ↗嗯。我不知道自己是否能接受这一点。你是说完全不尝试识别并排除不合作的节点?我怀疑这会带来麻烦,甚至可能遭受拒绝服务攻击。
这里不依赖于识别任何人。正如你所说,这样做徒劳无功,很容易用马甲账号绕过。
证明某个参与者真实存在的凭据,是他能够提供 CPU 算力。
引用的来信Ray Dillinger来源 ↗直到……直到什么时候?谁能知道一笔交易何时变得不可撤销?“几个”区块是三个?三十个?一百个?这取决于节点数量吗?与节点数量呈对数关系还是线性关系?
第 11 节计算了遭受攻击时的最坏情况。通常,5 或 10 个区块就足够了。如果你卖的东西不值得别人为了偷走它而发起全网规模的攻击,那么实际操作中可以把等待时间缩短一些。
引用的来信Ray Dillinger来源 ↗但是,如果没有身份信息,只要他们已经拿到双重支付所换来的商品(网站访问权限、下载,或者别的东西),支付变得无效对他们就没有坏处。商家只能承担“无效”币的损失,除非先等待那神奇的“几个区块”(又怎么知道该等几个?),再认定付款人已经付款。
如果消费者花了币后,需要一小时结清才能使用购买的东西,他们就不会这么做。如果商家发现收到的币因顾客双重支付而无效,却无法向顾客追收款项,商家也不会这么做。
这是第 2 版要解决的问题,我相信对于大多数应用,都能找到相当令人满意的解决办法。
这里比的是谁先把交易传播到网络中。想想 6 个自由度——传播是指数式的。只需大约 2 分钟,交易就能传播得足够广,使迟一步开始的竞争交易几乎无法在第一笔交易覆盖全网之前抢到太多节点。在这 2 分钟里,商家的节点可以监测双重支付交易。双重支付者无法把替代交易发遍全球,却不让商家收到,所以他必须等待之后才能开始。
如果真实交易到达了 90% 的节点,而双重支付交易到达了 10%,双重支付者就只有 10% 的概率不用付款,却有 90% 的概率花掉自己的钱。对于几乎任何商品,这都不值得骗子去做。
网站访问权限或下载这类信息商品无法销赃。没人能靠偷网站访问权限或下载来谋生。他们可以去文件共享网络盗取那些东西。大多数即时访问产品,都不会让人有很强的动机去偷。
如果商家确实遇到了盗取问题,可以让顾客等 2 分钟,或等待通过邮件收到相关内容,很多商家已经这么做了。如果他们真的想优化,而且是较大的下载,可以在交易被判定为双重支付时中途取消下载。如果是网站访问权限,通常先让顾客访问 5 分钟,等交易被拒绝后再切断访问,也不是什么大问题。反正很多这样的网站都有免费试用。
Satoshi Nakamoto
James A. Donald 写道:
James A. Donald 写道:
引用的来信James A. Donald来源 ↗那么,在竞争中落败的币怎么样了?
……如果排第二的人很可能失去他的币,那就有点太苛刻了。
同一笔交易出现多个双重支付版本时,有且只有一个版本会变为有效。
收款人必须等待大约一小时,才能相信付款有效。到那时,网络会解决所有可能的双重支付竞争。
收到那笔后来无效的双重支付的人,从一开始就不曾认为自己已经拿到了钱。他的软件会显示这笔交易从“未确认”变为“无效”。必要的话,界面可以隐藏交易,直到它在区块链中的深度足够。
引用的来信James A. Donald来源 ↗此外,你对事件的描述暗示了时间和货币生成方面的限制——整个网络生成币的速度,要比新币的消息传遍网络所需的时间慢。
抱歉,我可能没有说清楚。区块之间的目标间隔可能会定为 10 分钟。
每个区块都包含其创建时间。如果时间偏差超过 36 小时,其他节点就不会在它的基础上继续工作。如果最近 62430 个区块的时间跨度小于 15 天,就说明区块生成过快,工作量证明难度会加倍。所有人用相同的链数据进行相同的计算,因此都会在链上的同一位置得到相同结果。
引用的来信James A. Donald来源 ↗我们希望付款人在支付消息传遍网络时,就能确定交易有效,而不是等到分支之间的竞争得出结果时。
系统不具备即时不可撤销性,但仍然比现有系统快得多。纸质支票可能在一两周后被退票。信用卡交易可能在 60 至 180 天后被提出异议。比特币交易在一两小时内就能达到足够的不可逆程度。
引用的来信James A. Donald来源 ↗如果一个节点忽略了所有它不关心的支付,它也不会受到任何不利影响。
借助我最近发布的基于手续费的激励系统,节点就有动力纳入收到的所有付费交易。
Satoshi Nakamoto
手续费与交易优先级
25 条
这里有一种设计,可以留待很久以后考虑:
不是 locktime。
这里有一种设计,可以留待很久以后考虑:
你有意写一笔双重支付。用同样的输入和输出再写一遍,但这次带上手续费。当你的双重支付进入区块时,第一笔支出就失效了。收款方其实不会察觉,因在新交易生效的那一刻,旧交易就失效了,新交易直接取而代之。
说起来容易,实现起来难。要写出一个能正确构造双重支付的客户端、在钱包里管理两个版本直到其中之一被选中、处理好所有边角情况,工作量不小。现有代码里的每一个假设都是「你不会试图写双重支付」。
比特币矿工侧也需要一些改动,让交易池有可能接受双重支付,但只严格限于输入输出匹配且手续费更高的情况。目前,双重支付从不被交易池接受,因此每个节点都通过尝试将自己最先看到的那笔交易打包进区块,为这笔交易的先后顺序作证。
感谢 m0mchil 持续跟进更新!
其他参与者原话m0mchil原帖 ↗更新到 SVN 186
感谢 m0mchil 持续跟进更新!
GPU 矿工们,请尽快升级,终结免费交易滥用!这个版本新增了基于优先级的限制,用来抑制垃圾免费交易。
其他参与者原话m0mchil原帖 ↗刚更新到 SVN 181,并修正了 getwork 补丁:每次用新交易重建区块后,等待 60 秒再重建。这其实是原版客户端的行为,补丁里误漏掉了。修复了每个 getwork 请求都导致 CPU 占用过高的问题(在最近大量交易垃圾攻击下变得很明显)。请升级。
在 SVN 184 之前,把交易打包进区块用的是 n^2 算法。新的高效单遍算法要快上几个数量级。(O(n) 对比 O(n^2)/2,n=200 时约莫快 10 到 100 倍)
我正在做的就是类似的事。优先级就是你描述的这个概念更正式化的版本。
其他参与者原话creighto原帖 ↗或许在最近实现的年龄优先级规则之外,还应加一条无手续费交易的最小年龄规则。换句话说,或许能定一条生成规则:免费交易务必埋深 3 个区块之后才能再次免费转账。这样真实用户在必要时仍可立即花掉新资金,同时仍能按需重新调配资金,而无需额外成本。我认为这会显著抑制目前正在进行的垃圾交易攻击。
我正在做的就是类似的事。优先级就是你描述的这个概念更正式化的版本。
其他参与者原话FreeMoney原帖 ↗按现状,3.15 有不少免费交易空间,这些空间优先给 [年龄]*[金额]/[大小] 最高的交易,对吧?划出一部分免费交易空间要求 [年龄]*[金额]/[大小] > C 是否合理?
也许可以这样设定 C:一笔标准的 1 BTC 交易能进入下一个区块的主要免费交易区域,而 .1 BTC 的交易要等约 10 个区块才能进入。再让允许 [年龄]*[金额]/[大小] < C 的区域每次放行十来笔交易。
是的,就像这样。不要求优先级的区域是 3K,每区块约十来笔交易。
我刚上传了 SVN r185,对免费交易设置了最低优先级要求。交易洪水由反复转手的币构成,因此它们反复依赖自己的 0 确认交易。0 确认交易优先级为 0,这类免费交易就只能逐笔等待,每次等一笔交易先进入区块。
0.3.15 版只有在别无选择时,才会创建依赖 0 确认交易的新交易,因此普通用户通常不会遇到这个问题。
我认为这是在把默认手续费设为 0.01 之外的一个好折中。要求通过免费交易周转比特币时,频率不能过高,并不算过分。你用免费交易,就是在接受施舍,而同一批币能多频繁地享受这种施舍,总得有个上限。
我们一直说免费交易可能会处理得慢一些。加上 -paytxfee=0.01 能帮你确保交易快速通过。
你应该让交易至少具备一定优先级,以防下一个区块到来之前出现洪水攻击。
其他参与者原话ByteCoin原帖 ↗当然,如果网络没有被垃圾交易淹没、你也不太在意当前这笔交易被耽搁,那么优先使用你的 0 确认交易可能更划算,这样可以把较高优先级的币「省」下来,留到网络真的被淹没时用。
你应该让交易至少具备一定优先级,以防下一个区块到来之前出现洪水攻击。
只要所有依赖的交易都至少有 1 个确认,如果交易一开始优先级不够,前序交易的年龄会随着时间推移而增长,直到这笔交易的优先级足够高为止。
其他参与者原话ByteCoin(续)原帖 ↗当然,像我上面说的那样往交易里塞入约 1,000 个刚周转过的 BTC 来抬高优先级,这种钻空子的手法依然有效!
或者管理你在每笔交易上花费多少优先级。软件得预知你未来的计划,才能知道应该现在花掉优先级还是留到以后。不过我觉得我们不需要做到这么细。正常用户和攻击者之间的差异足够大。
优先级不必包办一切。一旦确认有洪水攻击,你能加上 -paytxfee=0.01。希望有了优先级机制,你在此之前发出的交易最坏也只是慢,而不是卡死。
感谢你们把洪泛测试限制在测试网。
感谢你们把洪泛测试限制在测试网。
0.3.15 版组合了多项功能,帮助正常交易在洪水攻击期间优先得到处理。关键在于 Gavin 的想法:根据交易所依赖的前序交易的年龄来安排优先级。每一枚币都有权按一定频率转手。等得越久,累积的优先级越高。优先级 = sum(valuein * age) / txsize。手续费仍然优先于优先级,而优先级决定同一费率层内的处理顺序。
为支持优先级功能,SelectCoins 只在万不得已、只剩下你自己的 0 确认交易时才使用它们。这样可以避免你过于频繁地周转自己的币,除非你确实在快速周转全部持币,强行让程序这样做。
能请几个人跑一下这个特别构建吗?它会特赦那些粉尘垃圾交易,从而暂时解决 0/unconfirmed 问题。我们其实只需要一个…
能请几个人跑一下这个特别构建吗?它会特赦那些粉尘垃圾交易,从而暂时解决 0/unconfirmed 问题。我们其实只需要一个放行它们的区块,就能清理掉以前的交易。如果你用它生成了区块,请回帖。
这些只有二进制包。linux 版只有 64 位。
http://www.bitcoin.org/download/bitcoin-0.3.13.1-specialbuild-win32.zip
http://www.bitcoin.org/download/bitcoin-0.3.13.1-specialbuild-linux64.tar.gz
SHA1 fb7c66270281ed058c570627cf7baff0bdc16e5d bitcoin-0.3.13.1-specialbuild-win32.zip
SHA1 9fc44ea5f2109618073e2cfd887e2cc266eb31a9 bitcoin-0.3.13.1-specialbuild-linux64.tar.gz
linux 64 位版针对 64 位模式下的 AMD,修改了 cpuid 4 路 128 位 SSE2 自动检测;如果你愿意,可以测试一下,看看是否有所改善。
没错,这个开关应该更动态、按 KB 付费。只是更难想清楚该怎么解释。
随着区块逐渐填满,它会逐步提高手续费要求:
随着区块逐渐填满,它会逐步提高手续费要求:
<50KB 免费
50KB 0.01
250KB 0.02
333KB 0.03
375KB 0.04
以此类推。
这是典型的定价机制。前 50KB 卖完后,价格涨到 0.01。250KB 卖完后,涨到 0.02。到了某个价格,只要你愿意出价比其他客户高,你几乎总能挤进去。
只附上最低的 0.01 就已经大有帮助。
我已在 SVN rev 157 里实现了这个改动。
中本聪原话中本聪原帖 ↗现在的门槛是每区块 200KB,约合每区块 1000 笔交易。我认为应该降到每区块 50KB。那仍然是平均每区块交易量的 100 多倍。
我已在 SVN rev 157 里实现了这个改动。
我之前把门槛设得那么高,是为了让数据量很大的交易也不必支付手续费。对于由一笔笔 50 BTC 挖矿奖励组成的交易,这个门槛大约相当于 26,000 BTC。尽管当时挖矿比现在容易 100 倍,也只有极少数人达到过这个手续费门槛。新门槛下,转出挖矿所得时大约到 11,000 BTC 才会触发手续费,而且主要只有挖矿所得才容易遇到这种情况。如果你的比特币是买来的,它们通常来自金额更大的交易,离手续费门槛还很远,除非你分几百笔交易买入。即使真的达到门槛,也只需要付一次手续费,就能把这些零碎款项合并起来。
修复在 SVN rev 151。
我猜我知道发生了什么。双击那笔挖矿交易。它里面很可能带了一笔低于 0.01 的手续费。
我猜我知道发生了什么。双击那笔挖矿交易。它里面很可能带了一笔低于 0.01 的手续费。
有人一直在付 0.00000010 的手续费。我觉得用 -paytxfee 你连这个都设不出来,得改代码才行。你生成的区块价值 50.00000010,因此当你试图把整笔发出去时,只剩 0.00000010 当找零,这就触发了针对粉尘垃圾交易的 0.01 手续费。
除了这个边界情况,它通常不会造成问题。我应该给 CreateTransaction 加个特例来处理这种情况。
出事的那个是什么版本?发布版,还是自己构建的?什么操作系统?
出事的那个是什么版本?发布版,还是自己构建的?什么操作系统?
你是用 IP 发的还是用 Bitcoin 地址发的?
你发 49.99 时,它有没有提示你付 0.01 手续费?
GetMinFee 有过一个改动,但我看不出它怎么会导致这个。它只在区块变得巨大时才开始生效。
区块数不同的原因,是 0.3.11 里把显示数字减了 1,因那样更合理。
目前,付不付手续费由 -paytxfee 开关手动控制。让软件自动检查最近区块的大小、判断是否该付手续费,相当容易。我们离触…
目前,付不付手续费由 -paytxfee 开关手动控制。让软件自动检查最近区块的大小、判断是否该付手续费,相当容易。我们离触及门槛还远得很,暂时不需要。而且先看看手动控制的效果如何,本来就是个好主意。
就算到了门槛也没什么大不了。免费交易只是要花更久才进区块。
我粗略统计了 74000-78000 附近的 4000 个区块。这不包括区块奖励交易:
平均每区块 2 笔交易、每小时 17 笔、每天 400 笔。
平均每个区块中的交易数据共 428 字节,即每笔交易 214 字节。
现在的门槛是每区块 200KB,约合每区块 1000 笔交易。我认为应该降到每区块 50KB。那仍然是平均每区块交易量的 100 多倍。
门槛将来很容易调整。到时候我们能决定调高。把门槛保持在较低水平,用作断路器,并按需提高,是个好办法。如果现在就触及门槛,那几乎肯定是某种洪水攻击而不是真实使用。保持较低门槛有助于在这种情况下限制浪费的磁盘空间。
另一个选项是降低每个区块允许的免费交易数量,超过之后才要求手续费。节点每个区块只接受一定 KB 的免费交易,超过后就开始要求…
另一个选项是降低每个区块允许的免费交易数量,超过之后才要求手续费。节点每个区块只接受一定 KB 的免费交易,超过后就开始要求至少 0.01 手续费。
这个门槛应该比现在更低。
我认为门槛永远不该是 0。我们应该始终允许至少一些免费交易。
-paytxfee 允许你在交易里附带手续费。如果交易确认变慢了,你可以用 "-paytxfee=0.01" 来获得优先。你…
不,不是这么回事。
-paytxfee 允许你在交易里附带手续费。如果交易确认变慢了,你可以用 "-paytxfee=0.01" 来获得优先。你发出的每笔交易都会多花 0.01。没有理由设得比 0.01 更高。
它只是放在那里以防万一。多半用不上,真用上了再细说也不迟。
我想不出实现它的办法。所有手续费都会是额外的交易。那么支付手续费的交易本身所需的手续费,又该怎么办?
我不知道怎么实现这个。给区块创建者的手续费用了一个特殊技巧,让手续费不占任何额外空间。如果每笔手续费都是一笔交易,那么支付手…
忘了补充微支付有利的一面。虽然我认为 Bitcoin 目前对更小额的微支付不实用,但随着存储和带宽成本持续下降,它最终会变得…
忘了补充微支付有利的一面。虽然我认为 Bitcoin 目前对更小额的微支付不实用,但随着存储和带宽成本持续下降,它最终会变得实用。如果 Bitcoin 大规模流行,到那时也许已经是这样了。让这类微支付更实用的另一个办法,是实现纯客户端模式(client-only),并让网络节点集中到数量较少的专业服务器集群中。无论你需要多小面额的微支付,最终都会实用。我想 5 年或 10 年后,带宽和存储都会显得微不足道。
我并不是说网络对 DoS 攻击免疫。我认为,大多数 P2P 网络都可能遭到多种形式的 DoS 攻击。(顺便说一句,我看到唱片公司想对所有文件共享网络发动 DoS,只是不想触犯反黑客/反滥用法律。)
如果有人开始通过大量来回转账的垃圾交易对我们发动 DoS 攻击,你就需要开始支付 0.01 的最低手续费了。0.1.5 其实有过设置它的选项,但我为了减少困惑把它拿掉了。免费交易是件好事,只要大家不滥用,我们可以一直这样。
这就引出一个问题:如果每笔交易有 0.01 的最低手续费,如果只是最低的 0.01,我们要不要自动加上?每次都问一遍会烦死人。如果你有 50.00、发送 10.00,收款方得到 10.00,你剩 39.99。我认为应该自动加上。跟其他许多服务自动附加的费用比,这算微不足道。
其他参与者原话FreeMoney原帖 ↗多打包交易会拖慢你的哈希速率吗?
不,完全不。
通常要超过 25,000 BTC。
对。否则我们无法给比特币设 2100 万的有限上限,因为生成永远需要某个最低回报。几十年后当回报变得太小,手续费将成为节点的…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
对。否则我们无法给比特币设 2100 万的有限上限,因为生成永远需要某个最低回报。几十年后当回报变得太小,手续费将成为节点的主要补偿。我相信 20 年后,要么交易量非常大,要么就没有交易量。
几乎所有交易都是免费的。如果一笔交易必须把 500 多笔你收到的最大额付款加总才能凑够金额,它就超过了最大数据体积限制。超限…
其他参与者原话theymos原帖 ↗发送方客户端会多发一些比特币来覆盖费用吗(这样收款方拿到的正是他期望的数额)?
会。
其他参与者原话SmokeTooMuch原帖 ↗为什么我们还需要费用?我以为"无费用"正是比特币的优点之一呢 ?!
几乎所有交易都是免费的。如果一笔交易必须把 500 多笔你收到的最大额付款加总才能凑够金额,它就超过了最大数据体积限制。超限交易加一笔小额费用仍可发出。
数据体积处于平均水平、以及不超过平均水平 500 倍的交易,都是免费的。
只有发送数据体积特别大的交易时才会收取手续费,即便这样,算下来也大约只有金额的 0.002%。这并非从系统里抽走的钱,它只是流向其他节点。如果你为付这笔费而难过,你随时可以反客为主自己运行一个节点,说不定哪天你自己就捞到一笔 0.44 的费用。
数据体积很大的交易需要支付一笔小额手续费。生成包含该交易的区块的节点会得到这笔费用。
数据体积很大的交易需要支付一笔小额手续费。生成包含该交易的区块的节点会得到这笔费用。
同一笔钱之后再次转出时,不会再次产生这笔费用。如果你的钱包里全是挖矿所得,又想一次全部转出,就必须在一笔数据体积很大的交易中,合并数百份每份 50 个比特币的挖矿奖励。完成这次合并后,以后再转出这笔资金时,交易里只需要一个输入项。
真奇怪,我见过 XP 上的 Firefox 3.5 对大号字体进行抗锯齿。不管怎样,你的办法更稳妥。
引用 Martti Malmi 的文字Martti Malmi来源 ↗引用中本聪此前的文字中本聪来源 ↗字体抗锯齿在哪个 Windows 版本/浏览器上不起作用?XP 上的 IE 6 有抗锯齿,比它更老的版本市场份额不到 1%。
XP 上的 Firefox 没有,IE 的效果也不如我在 Linux 上看到的。已附上 browsershots.org 的截图。
真奇怪,我见过 XP 上的 Firefox 3.5 对大号字体进行抗锯齿。不管怎样,你的办法更稳妥。
不过我暂时又改回了文字,这样可以继续调整颜色。Drupal 把 <span> 标签等杂项放进了浏览器标题,不过测试时没关系。
我在首页截图下面增加了一些说明文字。
引用 Martti Malmi 的文字Martti Malmi来源 ↗如果把同样的金额分成多笔小额发送,是不是就没有手续费了?
对。我想,对话框可能会让情况更糟,因为它给了人们尝试拆分的机会。
我正在做一些改动。免手续费交易的数据体积上限将是 60KB,如果由 50bc 的输入构成,大约相当于 27,000bc。我希望这个上限足够高,使手续费很少出现。v0.2 节点会接收免费交易,直到区块大小超过 200K,并优先处理数据体积较小的交易。
最好不要公开谈这些手续费的事。它是用来控制洪泛的。我们不想给任何人出主意。
引用 Martti Malmi 的文字Martti Malmi来源 ↗顺便问一下,手续费应该去哪儿?这次它和其他所有币一起到了收款人那里。已附上交易截图。
你发现了 CreateTransaction 中一个不常见的错误。它生成的交易金额是 10000.20,手续费为 0.22。如果你看发送方的交易,会看到扣款 10000.42,其中手续费 0.22。错误在于,在这种少见情况下,它需要第三次计算手续费,却把第一遍的手续费错误地加到了发送金额里。我会修复。
字体抗锯齿在哪个 Windows 版本/浏览器上不起作用?XP 上的 IE 6 有抗锯齿,比它更老的版本市场份额不到 1%。
字体抗锯齿在哪个 Windows 版本/浏览器上不起作用?XP 上的 IE 6 有抗锯齿,比它更老的版本市场份额不到 1%。
数据体积过大的交易,超过首个 1KB 的部分,每 KB 收取 0.01 手续费。首个 1KB 免费,体积较小的交易通常为 250 字节。双击那笔交易看看。可以把它想成按重量收取邮费。
解决办法是在发送时额外弹出一个对话框,例如:“这笔交易的数据体积较大,需要支付 0.20bc 的手续费。可以吗?”(这段文字够好吗,还是需要改进?)代码已经有了,我会加进去。
这样就不用解释那笔 10,000.20bc 的交易了,不过可能仍需要解释手续费归谁。
引用 Martti Malmi 的文字Martti Malmi来源 ↗文字标志其实看起来不错,除非是在字体抗锯齿不起作用的 Windows 上。我把它转成了 png。
我刚刚从一个账户向另一个账户转了 10,000bc,结果发出去的是 10,000.20bc。知道可能是什么原因吗?
引用中本聪此前的文字中本聪来源 ↗谢谢,我还没有确定主题。第一次尝试时,我想做点不一样的,别又是一个蓝色网站。另一个思路是做得像银行网站,庄重、专业,看起来正式,让人对金融事务更有信心。
标志有点太像迪斯科/90 年代网页。我还是更喜欢你在 bitweaver 上做的那个,目前先用文字重新做了一个占位。等主题更确定后,我再考虑搭配的标志。
Sourceforge 标记的主意不错,能得到的图形素材我们都用得上。
上线前我还有些事情要做,我们也需要给搜索引擎更多时间。
引用 Martti Malmi 的文字Martti Malmi来源 ↗我在 http://cooltext.com/ 自动生成了新标志,这是个不错的快速解决办法。如果你有耐心忍受缓慢的界面,可以在那里尝试各种不同的标志风格。
引用 Martti Malmi 的文字Martti Malmi来源 ↗如果你能从 SF 项目管理页面取得 Sourceforge 标志,并加到网站页脚,也会很好。
引用 Martti Malmi 的文字Martti Malmi来源 ↗目前网站的版式简洁好看。只是标志应该换掉。如果想尽快上线,可以先用网站标题代替,以后再做更好的标志。
如果网站管理需要帮助,或需要联系专业网页美术设计师,可以找 Dave。他的工作就是做 Drupal 相关的事。
收款地址与支付方式
15 条
最好默认禁用按 IP 收款,除非你明确打算用它。这是一大片无人使用的攻击面,没有必要默认开放。
最好默认禁用按 IP 收款,除非你明确打算用它。这是一大片无人使用的攻击面,没有必要默认开放。
在商店场景下,你通常只想让顾客通过你的自动化系统付款,它只发放与特定订单和账户关联的 bitcoin 地址。来路不明的付款随意发到服务器的 IP 地址上,并没有什么帮助。
总的来说,按 IP 发送的实用场景有限。如果不经代理直连,中间人风险或许能容忍,但没有隐私。如果你用隐私代理,中间人风险则高得不可接受。如果我们费劲实现了 SSL,通常只有大商家才愿意花功夫拿 CA 证书,而这些场景大多仍然用 bitcoin 地址更好。
我已把这个改动上传到 SVN rev 156。启用的开关是 "-allowreceivebyip"。
用这个版本的发送方会得到错误 "Recipient is not accepting transactions sent by IP address"。旧版本的发送方会得到 "Transfer was not accepted"。
我给开关用了不同的名字,因 "-allowiptransactions" 听起来像包含发送。如果这个开关有更好的名字,我们能再改。
后来发现,本来也没人喜欢那种转账方式,所以没怎么继续开发它。
但既然链接已经替你把字都打好了,我看不出用域名地址代替比特币地址有什么好处。用比特币地址,用户无法发出一笔无法确认归属的付款…
http://127.0.0.1:8330/?to=domain.com&amount=200.00&comment=order_12345
或
http://127.0.0.1:8330/?to=
但既然链接已经替你把字都打好了,我看不出用域名地址代替比特币地址有什么好处。用比特币地址,用户无法发出一笔无法确认归属的付款。在拿到一个正确的比特币地址之前,他们根本无法付款。
按域名发送的好处是你可以直观地核实钱发给了谁。
一个更关键的问题是:如果浏览器不被允许连接 127.0.0.1 怎么办:
http://bitcointalk.org/index.php?topic=63.msg1589#msg1589
而且如果真是这样,那个包含 127.0.0.1 的 freenet 链接示例又怎么说?
SirArthur 关于普通在线商家的观点很有道理,而那正是按 IP 发送选项更适合的场景。这种情况下,商家在静态 IP 上…
SirArthur 关于普通在线商家的观点很有道理,而那正是按 IP 发送选项更适合的场景。这种情况下,商家在静态 IP 上有自己的服务器、自己的域名和 SSL 证书。
我们可以不按 IP 连接,而是通过 SSL 连接一个域名,用现有的 CA 基础设施来认证你连上的确实是该域名的所有者。
用户发送到 domain.com(或 www.domain.com 也行)。那会非常自然,用户可以看到并核实自己输入的正是他要付款的对象。
SSL 也让 TOR 用户的安全得到保障。
问题是,我认为商家仍会更愿意用比特币地址,好确切知道这笔付款对应什么订单。你根本不能指望用户在备注栏里填对内容来标识交易。只有当我们有了 mailto 式的链接、能把订单号预填进备注栏,这才接近实用——但那样的话,链接里放一个比特币地址也照样行。
仅仅在 domain.com 上公开运行一个比特币服务器,让用户向它发送无法对应订单的付款,风险太大了。普通用户并不习惯必须在付款时注明用途。商家会收到许多未注明用途的付款,结果一周后收到一句"我付过钱了,我的东西呢?!"
付款流程里确实有一个步骤:接收方在接受之前验证订单。如果不包含有效的订单号,它可以拒绝付款并返回错误消息。不过,将定制代码与比特币服务器集成到这种程度,难度会很大。
现在的按 IP 发送没什么用:它连接到那个 IP,所以你为了匿名想用 TOR,可那样它就完全可能被窃听、被中间人攻击。
现在的按 IP 发送没什么用:它连接到那个 IP,所以你为了匿名想用 TOR,可那样它就完全可能被窃听、被中间人攻击。
未来按 IP 发送的计划是做成比特币地址加 IP 的形式,比如:
1auaDZCFYqaGx4FKS5WenNfurk2SkoDu4h
或
1auaDZCFYqaGx4FKS5WenNfurk2SkoDu4h
我需要分隔符字符的建议。":" 是个候选,但 IPv6 里也有 :,可能造成混淆。最好是 url 参数里允许的字符。
我想用 SSL 做连接,用比特币地址的公钥作为证书。这样你就能确定自己连上的正是你想要的对方,并且安全加密。比特币地址不用于交易,只用于认证。一个新生成的比特币地址会通过 SSL 连接发来。
既然经过了认证,就可以放心地用域名代替 IP 地址了。需要留意的是:如果用了代理,要用 socks4a 而不是 DNS 查询。
生成一个新的比特币地址,只在你自己的电脑上占用一点磁盘空间(大约 500 字节)。就像生成一个新的 PGP 私钥,只是 CP…
生成一个新的比特币地址,只在你自己的电脑上占用一点磁盘空间(大约 500 字节)。就像生成一个新的 PGP 私钥,只是 CPU 消耗更小,因为它是 ECC。地址空间实际上无限。它不伤害任何人,所以想生成多少就生成多少。
你生成的比特币地址会永久保留。必须保留一个比特币地址,才能证明发往它的东西归你所有。如果你能删除一个比特币地址而有人向它发了…
SheriffWoody:
你生成的比特币地址会永久保留。必须保留一个比特币地址,才能证明发往它的东西归你所有。如果你能删除一个比特币地址而有人向它发了款,钱就丢了。它们每个只有大约 500 字节。
sirius-m:
上千个自有地址完全不成问题。如果你已经生成了 50000 BTC,那你其实已经有 1000 个自有地址了,每生成 50 个就有一个。它们是隐藏的,不在 UI 里显示。
加一小段代码、给同一个 IP 持续返回同一个地址,是个好主意。我是这样用 C++ 做的:在对方使用之前,一直给同一个 IP 返回同一个密钥(即比特币地址):
// Keep giving the same key to the same ip until they use it
if (!mapReuseKey.count(pfrom->addr.ip))
mapReuseKey[pfrom->addr.ip] = GenerateNewKey();
...sends the key mapReuseKey[pfrom->addr.ip]
……之后……
// Received something with this key
mapReuseKey.erase(pfrom->addr.ip);
如果不方便知道何时收到过款,就每 20 分钟清一次缓存的密钥。
我想给 getnewaddress 加一个参数:若该地址在多少天内无收款就过期。
瞧,我们完全可以照同样的方式做,比如:
其他参与者原话Karmicads原帖 ↗
瞧,我们完全可以照同样的方式做,比如:
http://127.0.0.1:8330/?to=
Bitcoin 可以像在 8332 上应答 JSON-RPC 那样,在本地回环的 8330 端口上应答,给出 HTTP 应答。
其他参与者原话DataWraith原帖 ↗依我看,bitcoin 链接应该更像 mailto: 而不是 magnet:。
我想我们能办到。
虽然 Bitcoin 有可能在 HTTP 应答里呈现 HTML 界面、直接把事情办了,但作为用户,我会疑惑:是某个网站想骗我,还是我真的在和自己的 Bitcoin 服务器对话?
HTTP 应答可以只是一段带 JavaScript 的 HTML,等价于后退按钮,把浏览器送回原页面。然后 Bitcoin 弹出发送比特币对话框,目标比特币地址和金额已经填好。工作方式就像 mailto: 链接弹出一个已填好地址的新邮件。
127.0.0.1 回环对机器上的任何用户都可访问,没有按用户隔离,但这没关系,因为它只提供"预填对话框字段"的便利功能。你仍然得按发送。我们要确保发送按钮不处于选中状态,免得你正在敲空格或回车时它跳到前台。
在销售点用会很不错。收银机在屏幕上显示一个编码了比特币地址和金额的二维码,你用手机拍下来。
不是,每笔生成的交易都用一个新的、一次性的地址。
端口转发是把一个端口指向一台计算机。它告诉路由器由哪台计算机处理发往该端口的连接。所以收款的就是那台机器。
端口转发是把一个端口指向一台计算机。它告诉路由器由哪台计算机处理发往该端口的连接。所以收款的就是那台机器。
如果没设置端口转发,入站连接不会到达任何一台计算机,向该 IP 发送时只会提示无法连接收款方,什么也发不出去。按 IP 发送时,你其实仍是发到一个比特币地址:你的计算机连上那个 IP,向它索取一个新的比特币地址,把交易直接交给它,并确认它收到且接受。
应该有人把自己的静态 IP 贴出来,让大家试试按 IP 发送,顺便白送那个人一些钱。
比特币地址里有 32 位校验和,所以你不会不小心打错一个无效地址。
如果 4) 你发给了某个已抛弃或丢失 wallet.dat 的收款人,钱就丢了。这里有个微妙之处:既然流通中的总钱数变少了,每个人剩下的钱都会略微升值,即"自然通缩"。
谢谢你创建维护账号,没有它就不可能完成那些工作。我确实一直都会需要它。好的,我已经把密码改成 20 个字符的随机密码。
谢谢你创建维护账号,没有它就不可能完成那些工作。我确实一直都会需要它。好的,我已经把密码改成 20 个字符的随机密码。
这个域名不错。现在人们很少手动输入域名,都用自动补全,或者点击搜索引擎上的链接。
我需要提供一种办法,让你通过程序获取新生成的比特币地址。要么这样,要么让他们向你的 IP 地址付款,但那样就得依靠他们把订单号填进备注。
生成新地址时,可以有一个选项,在地址簿中添加与这个地址关联的条目,这样收到的交易就会带上标签。早期用户觉得标签令人困惑,所以我把它们藏起来了些,但对这个应用会很有帮助。你得把备注列拉宽,才能看到。
你会手动审核和录入订单吗,至少一开始这样做?我肯定会。
我在想,应该把界面改成:用户想要比特币地址时,主动申请。“给我一个用于收款的比特币。”我想,在发送按钮旁边加一个接收按钮,按下后显示“这是供你使用的新地址,这个按钮可以把它复制到剪贴板,你想给它加标签吗?”,也许再解释一下为什么不该重复使用地址。
或者干脆在地址框旁边放一个“新地址”按钮,每次都应该按一下,换个地址。
引用 Martti Malmi 的文字Martti Malmi来源 ↗我已经注册了 bitcoinexchange.com 域名,不久后会开始编写这个服务,当作一项不错的业余活动。我设想的是类似 Google 的简洁界面,无需注册,首页只有两个文本框:填入想交易的金额,再填用于购买美元的 PayPal 地址,或者用于购买比特币的比特币地址。下一页会给你一个新的比特币地址,用来发送币,或者一个校验码,填入 PayPal 交易文本。
一开始用 PayPal 很合适——简单,也没有启动成本,但以后我也许会接受信用卡。
你还需要维护账号吗?需要也没问题,但请把密码改成别的。
发送到比特币地址的交易总会显示“来自:未知”。交易只说明收款对象是谁。按比特币地址发送存在一些问题,但能有这样一个备用选项,…
谢谢。我把 50 枚币发回给你了,现在我们两清了。
不知道为什么,你发给我的转账显示为‘来源:未知(From: unknown)’,尽管我已经把你加入了地址簿。
我的交易列表里有一条‘已生成(未被接受)(Generated (not accepted))’,似乎某次生成币的尝试出了问题。我不确定发生了什么——是不是我的节点成功解出了一个区块,但还没把它发送到网络上,我就离线了?
我想,要在交易中发送元数据,得用其他机制。例如,广播与交易关联的加密消息,让它们保存一段时间(比如一个月),并对节点用于存储消息的空间设定某种限额。另一种办法是,收款人生成一个对自己有意义、对别人却没有明确含义的参考编号,再交给付款人。这样就不需要加密,可以直接把它放进区块里。
收到 50 了。
发送到比特币地址的交易总会显示“来自:未知”。交易只说明收款对象是谁。按比特币地址发送存在一些问题,但能有这样一个备用选项,无论对方是否在线都能向其付款,实在很好。以后有几个想法可以尝试改进。如果事情像现实世界一样发展,绝大多数交易都是与商家进行,那么目前商家基本上总会确保设置好按 IP 接收。点对点文件共享网络似乎相当成功,能让很大比例的用户设置防火墙,转发一个端口。
“已生成(未接受)”通常发生在两个节点几乎同时找到区块时,其中一个不会被接受。这是正常而且无法避免的。我计划在 v0.1.6 中隐藏这些条目,因为它们只会令人困惑和烦恼,用户没有必要看见。在网络像现在这样规模仍小时,如果你不能接受入站连接,就会更吃亏,因为你无法那么直接地收到区块公告。
第一个默认地址在创建时,标签是“Your Address”。
引用的来信Dustin D. Trammell来源 ↗引用的中本聪旧文中本聪来源 ↗那应该是你在家里用来收款的比特币地址。软件无法知道钱是谁发来的,因此它最多只能告诉你,是通过你的哪个地址收到的。你可以创建多个地址,给每个人一个不同的地址,再给它们加上标签,帮助你辨认是谁在给你付款。
啊!我甚至没注意到那是我家里的地址,你说得对 (: 我确实在家里创建了多个地址,所以没想到这一点。
引用的中本聪旧文中本聪来源 ↗除非你告诉它,否则它不知道任何名字。那里显示的名字,是你在地址簿里为那个地址关联的名字,可能在 Address Book 按钮下,也可能在你比特币地址右侧的“Change...”按钮下。
啊,你说得对,在 Change 按钮里的地址中,“Satoshi”关联到了接收这笔付款的地址。不过我不记得设置过这个值,是默认值之类的吗?(这是我第一次运行程序时,它自己生成的第一个默认地址)
第一个默认地址在创建时,标签是“Your Address”。
所有设置地址簿标签的地方,都是由用户手动设置的。唯一会自动添加标签的情况,是向新地址发送付款时添加一个空白标签。我猜你可能给一个以为是我的地址输入了标签,但软件让人困惑,所以你把它放错了地方。
给收款地址设置地址簿标签确实让人困惑,但我不确定还能怎么做。只要用途稍复杂一些,使用者就需要为每位付款人创建不同的收款地址,才能知道谁给自己付了钱。这个概念在现实世界里没有太多类似的东西。
Satoshi
阅读完整通信正文 · Dustin Trammell · 2009-01-20 · 收款地址的界面用语
这样就说得通了,我敢说当时就是这么回事。
我想,如果显示的是“Received with address: X”(通过地址 X 收到),而不只是“Received with: X”,我应该就明白了。不过,我确信那个地址被错误地标成“Satoshi”,才是我最初困惑的主要原因。你说得对,在人们熟悉的现有金融系统里,确实没有什么很相似的东西,也许除了 PayPal 可以使用多个收款邮箱这一点。或许可以写成“Received payment to: X”(收到付给 X 的款项)?
-- Dustin D. Trammell dtrammell@dustintrammell.com http://www.dustintrammell.com
那应该是你在家里接收这笔付款的比特币地址。程序无法知道款项来自谁,所以最多只能告诉你,是用你的哪个地址接收的。你可以创建多个…
那应该是你在家里接收这笔付款的比特币地址。程序无法知道款项来自谁,所以最多只能告诉你,是用你的哪个地址接收的。你可以创建多个地址,给每个人不同的地址,再加上标签,帮助判断是谁在给你付款。
除了你告诉它的名字,它不知道其他名字。那里显示的名字,是地址簿中与该地址关联的名字,可以通过“地址簿”按钮,或者你的比特币地址右侧的“更改……”按钮找到。
引用的来信Dustin D. Trammell来源 ↗Satoshi,你好,
第一次转账 25.00 之后,你没有再给我发 100.00 吧?我在工作地点的 BitCoin 程序里,用比特币地址而非 IP,向家里的程序发送了 100.00。家里的程序显示收到了一笔 100.00 的转账,但交易详情写着“接收地址:Satoshi 12higDjoCCNXSA95xZMWUdPvXNmkAduhWv”。那不是我工作地点的比特币地址,所以我猜,这是不是表示我收到的付款,被编码进了由你的客户端计算出的一个区块?如果是这样,除了生成它的比特币地址,程序怎么还知道你的名字?我不记得程序里有可以填写自己名字的地方。
-- Dustin D. Trammell dtrammell@dustintrammell.com http://www.dustintrammell.com
商家如何正确记账
15 条
一个使用 0.3.18 新的基于账户命令的伪代码示例。
一个使用 0.3.18 新的基于账户命令的伪代码示例。
print "send to " + getaccountaddress(username) + " to fund your account"
print "balance: " + getbalance(username, 0)
print "available balance: " + getbalance(username, 6)
// if you make a sale, move the money from their account to your "" account
if (move(username, "", amount, 6, "purchased item"))
SendTheGoods()
// withdrawal
sendfrom(username, bitcoinaddress, amount, 6, "withdrawal by user")
你能用 listtransactions(username) 向他们展示其近期交易列表。
只要这个接口的定位是向用户展示最近 N 笔交易历史之类的用途,就没问题——何况现在有了账户功能,用正确的方式做支付检测更容易…
其他参与者原话jgarzik原帖 ↗关于「
之后的交易」,我同意你和中本聪的看法。我的 listtransactions(现在叫 xlisttransactions)补丁刻意不提供那个功能,从来都没有。
只要这个接口的定位是向用户展示最近 N 笔交易历史之类的用途,就没问题——何况现在有了账户功能,用正确的方式做支付检测更容易了。
Gavin,listtransactions 能不能加个选项,列出所有账户的交易?
我不确定接口应该是什么样,也许:
listtransactions
不过从命令行做这个会很别扭。
我想不出接口的好方案,问题就在这。也许像 "" 一样来个 "*" 特例。这样人人都得确保没有用户能创建名为 "*" 的账户。
其他参与者原话jgarzik原帖 ↗当然,用交易来追踪这一点相当容易。
我不明白用交易追踪这事儿怎么就「相当容易」了。
我说的不是某个 minconf 水平下的正常风险,我说的是这样使用 listtransactions 带来的额外陷阱。
我说的不是某个 minconf 水平下的正常风险,我说的是这样使用 listtransactions 带来的额外陷阱。
中本聪原话中本聪原帖 ↗2) 发生区块链重组时,交易重新确认后很容易被重复计数。
楼主的 listtransactions
一个函数看起来就是为某种显而易见的用法量身定做的,而那种用法却暗藏陷阱——这似乎不太妥当。
其他参与者原话jgarzik原帖 ↗在这个问题上,listtransactions 带来的风险并没有超出使用 listreceivedbyaddress 时已有的风险。
假设两笔支出都指向同一地址。getreceivedbyaddress 在任一时刻只会计入其中一笔支出,绝不会两笔都算。
用 listtransactions,两笔都算进去就太容易了。你看到第一笔支出,计入;看到第二笔支出,又计入。总额被重复计算。
那你如何应对我在你引用的那条消息里列出的问题?
这样使用 listtransactions 是不安全的。
这样使用 listtransactions 是不安全的。
我知道我一直因为对 listtransactions 迟迟不肯松口而挨批。让我解释一下我为什么犹豫。
交易是动态的。过去的交易或许会失去确认、消失又回来、失效并彻底消失,或者被另一笔双重支付取代。它们的日期或许会变,顺序也或许会变。
程序员很自然地会想这样使用 listtransactions:把自上次查询以来的新交易提供给我,我自己记账或保存静态记录。这在一切常规使用中似乎都没问题,但只要你依据这些金额做任何操作,这种做法就很容易被利用:
1) 你怎么知道一笔过去的交易失效并消失了?
2) 发生区块链重组时,交易重新确认后很容易被重复计数。
3) 一笔交易或许被 txid 不同的双重支付取代。你会把两笔支出都算进去。
「我只需要看新交易、因之前的交易我已经看过了」这个假设模型不成立。旧交易随时可能改变。
每当你基于收到的支付金额采取行动,你都必须重新向比特币查询当前的总余额(或使用 move 或 sendfrom),并做好余额可能下降的准备。
现在我们有了账户功能,能更容易地按正确方式做事,因此推出 listtransactions 的时机更成熟了。
这是一段伪代码,演示怎么使用基于账户的命令。它确实让网站整合容易多了。
这是一段伪代码,演示怎么使用基于账户的命令。它确实让网站整合容易多了。
print "send to " + getaccountaddress(username) + " to fund your account"
print "balance: " + getbalance(username, 0)
print "available balance: " + getbalance(username, 6)
// 如果达成一笔销售,把钱从他们的账户里移出
move(username, "", amount, 6)
// 提现
sendfrom(username, bitcoinaddress, amount, 6)
我已经开始实现类似的功能。大体上和 Gavin 描述的一样。
我已经开始实现类似的功能。大体上和 Gavin 描述的一样。
再补充一些 rpc 接口:
move
从一个内部账户转到另一个。我想空白账户名("")会是你的默认账户。如果你卖东西给某个用户,能执行 move "theiraccount" "" 123.45。
这个操作叫 "move" 最合适吗?我避开了 "transfer",因它听起来太像发送一笔交易。
我在考虑新增一个 getaccountaddress 函数,而不是重载 getnewaddress:
getaccountaddress
给你一个从 getnewaddress
有了这些命令,在简单场景下,你能否无需自建数据库就实现自己的网站?
你需要用 listtransactions 做什么?
你需要用 listtransactions 做什么?
我当初不实现 listtransactions,就是想确保 web 程序员不会用它。人们很容易顺手拿它来盯收到的付款。走那条路没有任何可靠的办法保证什么都不漏。在我们拿出可靠的示例代码、演示 getreceivedbyaddress 和 getreceivedbylabel 的用法,并能指着代码说「用这个!用这个!别用 listtransactions!」之前,我认为不应该实现 listtransactions。
真要实现的时候,也许防止这种误用的一个办法是把它做成纯文本。不要把字段拆成 comment、confirmations、credit、debit 之类。可以是一个格式化好的字符串,比如 "0/unconfirmed 0:0:0 date comment debit 4 credit 0" 什么的,让程序员难以误用它来做程序化解析。它只是用来看服务器状态的。不过我猜这对想把内容格式化成 html 表格的 web 界面来说会有点烦。
我们需要有人写示例代码,最好是 Python 或 Java,展示用 JSON-RPC 接口创建账户系统的推荐方式。大多数卖东…
我们需要有人写示例代码,最好是 Python 或 Java,展示用 JSON-RPC 接口创建账户系统的推荐方式。大多数卖东西的网站都需要类似的东西。一直跟进这里 JSON-RPC 主题的人应该对它该怎么工作有概念。
用户登录自己的账户后,你展示他能汇入资金的比特币地址。展示之前,先检查这个地址是否已被用过,用过就换新的(getnewaddress
用 getreceivedbylabel
如果你要求多于 0 个确认,最好同时展示当前余额(0 确认)和可用余额(1 个或以上确认),这样用户能立刻看到付款已被接收。不是所有网站都要等确认,所以「当前 + 可用」双余额应该是可选的。卖数字商品的网站大多 0 确认就够。
一个合适的示例应用是个简单的银行网站:具备以上功能,外加向比特币地址付款的选项。示例代码应该尽可能简单,只带让它成为可用网站的最少东西。
vekja.net 就是这类网站的一个例子。
这是个 wxWidgets 应用,所以没有 main() 函数。不久之后也许就有了,因为我离让 bitcoind 不依赖 w…
在 init.cpp。
这是个 wxWidgets 应用,所以没有 main() 函数。不久之后也许就有了,因为我离让 bitcoind 不依赖 wxBase 编译已经很近了。(到时候会放在 init.cpp)
我把文件命名成 "main.cpp",抱歉,当时另一个可选名字是 "core.cpp"。现在改太迟了。不过我还是更喜欢 main.cpp。
我们仍然非常缺示例代码,展示使用 JSON-RPC 函数的推荐方式,比如给一个典型的购物网站做基本的账户系统。用 getreceivedbylabel、以用户名做 label,账户存的地址被用过之后就换一个新比特币地址。我在论坛某个地方贴过一段示例代码片段。(搜 getreceivedbylabel 或 getnewaddress)示例代码可以是一个最普通不过的银行网站,可以存款、可以付款。
我一直想鼓励有人写一些示例 Python 代码并发布出来,展示做常规记账事务的推荐方式,但都没下文。要是你不必像现在这样重新…
我一直想鼓励有人写一些示例 Python 代码并发布出来,展示做常规记账事务的推荐方式,但都没下文。要是你不必像现在这样重新发明轮子就好了。搜 getnewaddress,你应该能找到一个我贴过一小段示例伪代码的主题。
我担心太多程序员会拿它去检查收款。那样永远不可靠。list/getreceivedbyaddress/label 函数才是可…
我加了几个与标签相关的函数,帮助管理每个用户的多个地址。新增或更名的函数:
我加了几个与标签相关的函数,帮助管理每个用户的多个地址。新增或更名的函数:
getreceivedbyaddress -- 单个地址收到的金额
getreceivedbylabel -- 带此标签的所有地址收到的金额
listreceivedbyaddress -- 列出地址及其收到的金额
listreceivedbylabel -- 列出标签及其收到的金额
setlabel -- 为完整性补充的其他标签函数
getlabel
getaddressesbylabel
为保持一致,我把 getamountreceived 更名为 getreceivedbyaddress、getallreceived 更名为 listreceivedbyaddress。旧名字仍在,以免破坏现有代码,但已弃用。
思路是:只要你在调用 getnewaddress 时提供用户名,就能用 "bylabel" 函数取得该用户在所有地址上的收款总额。你可以随意更换他的地址,不必操心追踪他所有旧地址。
自动更换用户收款地址的好办法:就在显示他当前地址之前,检查它是否收到过任何东西,如果有就换成新地址:
// Get a new address whenever the current one has received anything
if (strAddr == "" || getreceivedbyaddress(strAddr) > 0)
strAddr = getnewaddress(strUsername); // Label the address with username
Display(strAddr); // Display their current receiving address
// Get total received by all the user's addresses
getreceivedbylabel(strUsername, 0) // unconfirmed
getreceivedbylabel(strUsername, 1) // available balance
如果只是取某个特定用户的余额,比如响应那个用户的页面请求,用 getreceivedbylabel;如果要遍历所有用户,最好用 listreceivedbylabel 拿到完整列表再对照结果扫描。用 getreceivedbylabel 扫描用户是 n 的平方,用 listreceivedbylabel 是 n-log-n(或 n 线性)。
其实只有当你为了"一收到钱就自发采取行动"而轮询、而不是用户打开网页看到余额后告诉你怎么处理时,才真正需要扫描全部用户。没必要轮询得太频繁。如果你要求 1 个确认,反正平均要 10 分钟,因此,没有必要比每几分钟一次更频繁地轮询。
如果你卖的是数字商品和服务——有人免费蹭到也没多大损失、也无法转卖牟利——我认为接受 0 确认没问题。
基本上只有卖黄金或货币时才需要多个确认。
是的,实际上它就是这样。getallreceived 0 就能满足你的要求。(现在它已更名为 listreceivedbya…
其他参与者原话molybdenum原帖 ↗或者一个可选参数指定该交易之后的最小区块数(getallreceived 1 为当前行为,或直接 getallreceived,getallreceived 5 给偏执狂,getallreceived 0 为即时确认)?
是的,实际上它就是这样。getallreceived 0 就能满足你的要求。(现在它已更名为 listreceivedbyaddress 0)默认是 1 个确认,但我认为实际上大多数数字商品和服务可以 0 确认。如你所说,如果你需要多于 0 个确认,可以显示两个数字:未确认余额和可用余额,这样他们立刻就能看到交易已经通过。
listreceivedbyaddress [minconf=1] [includeempty=false]
[minconf] 是款项被计入所需的最少确认数。
[includeempty] 是否包含尚未收到任何付款的地址。
返回一个对象数组,包含:
"address" : 接收地址
"label" : 接收地址的标签
"amount" : 该地址收到的总金额
"confirmations" : 所含最近一笔交易的确认数
或者,如果你用用户名给地址贴标签,就用 listreceivedbylabel。
到目前为止,我集中精力于面向 web 商家的函数,无界面挖矿机的远程管理功能还没怎么顾上。
如 riX 所说,这才是正路。软件可以在每次收款时按需生成新的比特币地址。"请发送 X 个比特币至 [一次性比特币地址] 以…
如 riX 所说,这才是正路。软件可以在每次收款时按需生成新的比特币地址。"请发送 X 个比特币至 [一次性比特币地址] 以完成订单"。服务器收到该地址上的这笔金额,就可以触发自动发货或给店主发邮件。
加命令行支持是高优先级。只是要有时间写代码。
目录与阅读顺序由本站整理;原话保留各自日期与上下文。文中软件版本、费用和设置属于当时的历史语境。