比特币上的有状态多重签名

news/2024/7/7 14:31:41 标签: 区块链, 智能合约, 脚本语言

无需链下通信

介绍

随着区块链和加密货币空间的发展,越来越需要增强安全措施来保护数字资产。 应对这一挑战的突出解决方案之一是多重签名(多重签名)钱包。 这些钱包在执行交易之前需要多方签名,从而提供额外的安全层来防止未经授权的访问和欺诈。

图片来源CoinDesk

图片来源CoinDesk

传统的多重签名钱包需要各方进行带外(链下)通信以收集所有签名。 我们引入了一种智能合约,可以直接在区块链上收集签名。 智能合约会跟踪这些签名,一旦达到设定的阈值,就可以解锁资金。 例如,当多重签名组中的各方彼此不认识时,这可能很有用。

传统多重签名钱包

多重签名钱包通常需要 M-of-N 签名(来自一组 N 个参与者的 M 个签名)来授权交易。 这些钱包在管理数字资产方面越来越受欢迎,特别是在以下场景中:

  1. 联名账户,需要多个家庭成员或商业伙伴批准交易。
  2. 托管服务,中立的第三方持有资金直到满足预定条件。
  3. 安全存储,一个用户持有多个密钥以防止未经授权的访问。

传统的多重签名钱包需要在各方之间交换部分签名的交易,然后才能将它们提交到链上。

链上签名收集

在接下来的步骤中,我们已经开发了一个允许链上签名收集的多重签名智能合约

  1. 智能合约部署在区块链上,指定最小签名数 M 和授权签名者列表 N。 它有一个状态:到目前为止收集的签名列表,初始化为零。
  2. 每当使用新签名调用合约时,如果它是有效的和新的,它就会被添加到状态中。
  3. 一旦达到阈值 M智能合约就会支付到预定义的目标地址。

下面是用 sCrypt 编写的完整代码。

export type Owner = {
    pubKey: PubKey
    validated: boolean
}

export class StatefulMultiSig extends SmartContract {
    // N of M signatures required.
    static readonly N = 2
    static readonly M = 3

    // Payment destination once signature threshold is reached.
    @prop()
    dest: PubKeyHash

    // Public keys of the owners along with boolean flags, that
    // indicate if their sig was already validated.
    @prop(true)
    owners: FixedArray<Owner, typeof StatefulMultiSig.M>

    constructor(
        dest: PubKeyHash,
        owners: FixedArray<Owner, typeof StatefulMultiSig.M>
    ) {
        super(...arguments)
        this.dest = dest
        this.owners = owners
    }

    @method(SigHash.ANYONECANPAY_SINGLE)
    public pay() {
        // Check if threshold was reached.
        let nValid = 0n
        for (let i = 0; i < StatefulMultiSig.M; i++) {
            if (this.owners[i].validated) {
                nValid += 1n
            }
        }
        assert(
            nValid >= BigInt(StatefulMultiSig.N),
            'Not enough valid signatures.'
        )

        // Make sure balance in the contract does not change.
        const amount: bigint = this.ctx.utxo.value
        // Pay destination address
        const output: ByteString = Utils.buildPublicKeyHashOutput(
            this.dest,
            amount
        )
        // Verify unlocking tx has this output.
        assert(this.ctx.hashOutputs == hash256(output), 'hashOutputs mismatch')
    }

    @method(SigHash.ANYONECANPAY_SINGLE)
    public add(sig: Sig, pubKeyIdx: bigint) {
        let added = false

        for (let i = 0; i < StatefulMultiSig.M; i++) {
            if (BigInt(i) == pubKeyIdx) {
                const owner = this.owners[i]
                const valid = this.checkSig(sig, owner.pubKey)
                if (valid && !owner.validated) {
                    // Toggle flag.
                    this.owners[i].validated = true
                    added = true
                }
            }
        }

        // Make sure at least one new valid sig was added.
        assert(added, 'No new valid signature was provided.')

        // Make sure balance in the contract does not change.
        const amount: bigint = this.ctx.utxo.value
        // Output containing the latest state.
        const output: ByteString = this.buildStateOutput(amount)
        // Verify unlocking tx has this single output.
        assert(this.ctx.hashOutputs == hash256(output), 'hashOutputs mismatch')
    }
}

合约源代码

该合约有两个公共方法:

它有两个公共方法:

  • add ——此方法将有效签名及其所属公钥的索引作为输入。 它首先检查此签名的有效性,如果有效则设置一个标志。
  • pay — 此方法检查是否已达到签名阈值,例如 在此特定示例中,阈值是三分之二。 如果是这样,它确保下一个输出将锁定资金支付到存储在 dest 变量中的地址。

完整的代码和测试可以在我们的样板存库中找到。


引用

扩展 UTXO 模型中的原生自定义令牌:https://iohk.io/en/research/library/papers/native-custom-tokens-in-the-extended-utxo-model/


http://www.niftyadmin.cn/n/5218551.html

相关文章

抖音开新店,十个设置,实操满满全是干货

抖店开店的第一天手足无措不知从哪入手&#xff1f;我给大家分享一个新手开店必须完成的十个设置&#xff0c;实操满满全是干货&#xff0c;每一项都很重要&#xff01;特别是新手一定要认真看&#xff0c;因为这个直接关系到你店铺能否正常经营&#xff0c;跟着我一起来实操一…

SparkDesk知识库 + ChuanhuChatGPT前端 = 实现轻量化知识库问答

上一篇 讯飞星火知识库文档问答Web API的使用&#xff08;二&#xff09; 把星火知识库搞明白了&#xff1b; 然后又花了时间学习了一下gradio的一些基础内容: 在Gradio实现两个下拉框进行联动案例解读&#xff1a;change/click/input实践&#xff08;三&#xff09; 在Gradio实…

不会提问不打紧,不敢提问才要命

最近在星球里回答了球友提出来的一些问题&#xff0c;我都给了回复&#xff0c;不经过在明确问题、探索问题的过程&#xff0c;对我启发挺大&#xff0c;特此来记录下感受和感悟。 缘起 最近新加入球友提的问题&#xff0c;有几次&#xff0c;我第一时间没看懂&#xff0c;甚…

Star History 十月开源精选 |AI for Postgres

在 2023 年 Stack Overflow 开发者调查中&#xff0c;Postgres 顶替了 MySQL 被评为最受欢迎的数据库。一个重要因素应该是 Postgres 支持扩展&#xff1a;可扩展的架构 Postgres 仍然由社区拥有&#xff0c;Postgres 生态近年来蓬勃发展。 扩展可以看作是内置功能&#xff0c…

sCrypt 在英国伦敦 Exeter 大学讲学

6月5日&#xff0c;sCrypt CEO晓晖和他的两位同事在英国伦敦Exeter大学举行了一场精彩的讲座。刘晓晖向听众们详细介绍了sCrypt智能合约开平台&#xff0c;并演示了如何使用sCrypt来开发基于比特币的智能合约。他用生动形象的语言&#xff0c;深入浅出地解释了这个领域复杂而又…

【非监督学习 | 聚类】聚类算法类别大全 距离度量单位大全

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

idea创建不了spring2.X版本,无法使用JDK8,最低支持JDK17 , 如何用idea创建spring2.X版本,使用JDK8解决方案

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对博主首页也很感兴趣o (ˉ▽ˉ&#xff1b;) &#x1f4dc;jdk17安装全方位手把手安装教程 / 已有jdk8了&#xff0c;安装JDK17后如何配置环境变量 / 多个不同版本的JDK&#xff0c;如何配置环境变量&a…

位图/布隆过滤器+海量数据处理总结

位图 题目&#xff1a; 第一种方法&#xff1a;二分查找。虽然二分的时间复杂度为o(log n),但是这个方法是不可行的&#xff0c;我们就算假设这40亿个数据是已经排序完成了的数据&#xff0c;但是40亿个整数在内存需要消耗的内存就是差不多16G&#xff0c;这个消耗是非常巨大的…