Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >区块链基础:交易简单实现

区块链基础:交易简单实现

作者头像
程裕强
发布于 2022-05-06 11:53:14
发布于 2022-05-06 11:53:14
94700
代码可运行
举报
运行总次数:0
代码可运行

1、交易输入

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.blockchain.model;

/**
 * 交易输入,UTXO=<txId,value>
 * 一个交易,可能有多个输入 
 */
public class TransactionInput {

    /**
     * 前一次交易id
     */
    private String txId;
    /**
     * 交易金额
     */
    private int value;
    /**
     * 交易签名
     */
    private String signature;
    /**
     * 交易发送方的钱包公钥
     */
    private String publicKey;

    public TransactionInput() {
        super();
    }

    public TransactionInput(String txId, int value, String signature, String publicKey) {
        super();
        this.txId = txId;
        this.value = value;
        this.signature = signature;
        this.publicKey = publicKey;
    }

    //省略getter和setter
}

2、交易输出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.blockchain.model;

/**
 * 交易输出,一个交易可能有多个输出
 */
public class TransactionOutput {

    /**
     * 收纳金额
     */
    private int value;
    /**
     * 交易接收方的钱包公钥的hash值
     */
    private String publicKeyHash;

    public TransactionOutput() {
        super();
    }

    public TransactionOutput(int value, String publicKeyHash) {
        this.value = value;
        this.publicKeyHash = publicKeyHash;
    }
    //省略getter和setter
}

3、交易参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.blockchain.model;

/**
 * 交易接口参数
 *
 */
public class TransactionParam {

    /**
     * 发送方钱包地址
     */
    private String sender;
    /**
     * 接收方钱包地址
     */
    private String recipient;
    /**
     * 交易金额
     */
    private int amount;

    //省略getter和setter

}

3、交易

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.blockchain.model;

import java.util.List;

import com.alibaba.fastjson.JSON;
import com.blockchain.security.CryptoUtil;
import com.blockchain.security.RSACoder;

/**
 * 交易类
 * 易过程中,转账方需要通过签名脚本来证明自己是 UTXO 的合法使用者易过程中,转账方需要通过签名脚本来证明自己是 UTXO 的合法使用者
 */
public class Transaction {

    /**
     * 交易唯一标识
     */
    private String id;
    /**
     * 简单交易输入(只有一个输入)
     */
    private TransactionInput txIn;

    /**
     * 简单交易输出(只有一个输出)
     */
    private TransactionOutput txOut;

    /**
     * 一般交易输入
     */
    private List<TransactionInput> txInList;

    /**
     * 简单交易输出(只有一个输出)
     */
    private List<TransactionOutput> txOutList;  

    public Transaction() {
        super();
    }
    /**
     * 简单交易:只有一个输入和一个输出
     */
    public Transaction(String id, TransactionInput txIn, TransactionOutput txOut) {
        super();
        this.id = id;
        this.txIn = txIn;
        this.txOut = txOut;
    }
    /**
     * 一般交易:多个输入和多个输出
     */
    public Transaction(String id, List<TransactionInput> txInList, List<TransactionOutput> txOutList) {
        super();
        this.id = id;
        this.txInList = txInList;
        this.txOutList = txOutList;
    }


    /**
     * 是否系统生成区块的奖励交易
     * coinbase交易的txIn是空值(前一次交易:id为0,value为-1)
     */
    public boolean coinbaseTx() {
        return txIn.getTxId().equals("0") && txIn.getValue() == -1;
    }

    /**
     * 付款人对交易进行签名确认,用交易发起者的私钥对交易的Hash数据进行签名:
     * (一般是发送者将信息用哈希算法处理得出一个哈希值,然后用私钥对该哈希值进行加密,得出一个签名。
     * 然后发送者再将信息和签名一起发送给接收者。
     * 接收者使用发送者的公钥对签名进行解密,还原出哈希值,再通过哈希算法来验证信息的哈希值和解密签名还原出来的哈希值是否一致,
     * 从而可以鉴定信息是否来自发送者或验证信息是否被篡改。)
     * 
     * 签名结果存入交易的输入中(txIn)
     *  
     * @param privateKey 交易发起者的私钥
     * @param prevTx
     */
    public void sign(String privateKey, Transaction prevTx) {
        if (coinbaseTx()) {//跳过挖矿系统奖励的交易
            return;
        }
        //交易输入引用的前一笔交易与传入的前一笔交易不匹配
        if (!prevTx.getId().equals(txIn.getTxId())) {
            System.err.println("交易签名失败:当前交易输入引用的前一笔交易与传入的前一笔交易不匹配");
        }

        Transaction txClone = cloneTx();
        //设置交易副本的txIn的公钥
        txClone.getTxIn().setPublicKey(prevTx.getTxOut().getPublicKeyHash());
        String sign = "";
        try {
            //用交易发起者的私钥对交易的Hash数据进行签名
            sign = RSACoder.sign(txClone.hash().getBytes(), privateKey);
        } catch (Exception e) {
            System.err.println("数字签名出错!");
            e.printStackTrace();
        }
        System.out.println("数字签名长度:"+sign.length());
        txIn.setSignature(sign);
    }

    /**
     * 生成用于交易签名的交易记录副本
     */
    public Transaction cloneTx() {
        TransactionInput transactionInput = new TransactionInput(txIn.getTxId(), txIn.getValue(), null, null);
        TransactionOutput transactionOutput = new TransactionOutput(txOut.getValue(), txOut.getPublicKeyHash());
        return new Transaction(id, transactionInput, transactionOutput);
    }

    /**
     * 收款人对付款人的交易签名进行校验
     * @param prevTx
     */
    public boolean verify(Transaction prevTx) {
        if (coinbaseTx()) {//跳过挖矿系统奖励的交易
            return true;
        }
        //交易输入引用的前一笔交易与传入的前一笔交易不匹配
        if (!prevTx.getId().equals(txIn.getTxId())) {
            System.err.println("验证交易签名失败:当前交易输入引用的前一笔交易与传入的前一笔交易不匹配");
        }
        Transaction txClone = cloneTx();
        //上个交易的输出指定了接受者的公钥,也就是当前交易发起者的公钥
        txClone.getTxIn().setPublicKey(prevTx.getTxOut().getPublicKeyHash());
        boolean result = false;
        try {
            //通过发送者的公钥进行签名校验
            result = RSACoder.verify(txClone.hash().getBytes(), txIn.getPublicKey(), txIn.getSignature());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 生成交易的hash
     */
    public String hash() {
        return CryptoUtil.sha256(JSON.toJSONString(this));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Transaction other = (Transaction) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

     //省略getter和setter
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于Java语言构建区块链(五)—— 地址(钱包)
在 上一篇 文章当中,我们开始了交易机制的实现。你已经了解到交易的一些非个人特征:没有用户账户,您的个人数据(例如:姓名、护照号码以及SSN(美国社会安全卡(Social Security Card)上的9 位数字))不是必需的,并且不存储在比特币的任何地方。但仍然必须有一些东西能够识别你是这些交易输出的所有者(例如:锁定在这些输出上的币的所有者)。这就是比特币地址的作用所在。到目前为止,我们只是使用了任意的用户定义的字符串当做地址,现在是时候来实现真正的地址了,就像它们在比特币中实现的一样。
王维
2018/04/12
4.5K3
基于Java语言构建区块链(五)—— 地址(钱包)
用NBitcoin进行区块链开发(5)
BTC的区块链(blockchain)存储着许多交易(transaction),transaction简单来讲是指BTC从某个地址到某个地址的转移记录。与我们平常的交易记录方式不太一样,一个交易主要由输入(value input)和输出(value output)构成。
申龙斌
2019/03/12
1.3K0
自己动手写区块链-发起一笔交易(Java版)
本文我们将会做以下事情: 1、创建一个钱包(wallet)。 2、使用我们的前面创建的区块链发送一笔签名的交易出去。 3、还有其他更叼的事情等等。 听起来是不是就让人心动。 最后的结果就是我们有了自己的加密货币,是的,crypto coin。 前面我们已经构建了一个基本的区块链。但目前这个区块链的区块中的message是一些没有什么实际用途和意义的数据。本文我们就尝试让区块中能够存储一些交易数据(一个区块中可以存储多笔交易数据),这样我们就可以创建自己的加密货币(当然还是一个简单的),这里给我们的货币起个名
ImportSource
2018/04/03
4.4K1
自己动手写区块链-发起一笔交易(Java版)
基于Java语言构建区块链(六)—— 交易(Merkle Tree)
在这一系列文章的最开始部分,我们提到过区块链是一个分布式的数据库。那时候,我们决定跳过"分布式"这一环节,并且聚焦于"数据存储"这一环节。到目前为止,我们几乎实现了区块链的所有组成部分。在本篇文章中,我们将会涉及一些在前面的文章中所忽略的一些机制,并且在下一篇文章中我们将开始研究区块链的分布式特性。
王维
2018/04/16
1.5K4
基于Java语言构建区块链(六)—— 交易(Merkle Tree)
区块链基础:交易模型解读
UTXO(unspent transaction output)未花费的交易输出,这是比特币交易中核心概念。
程裕强
2022/05/06
9210
区块链基础:交易模型解读
Bytom交易说明(UTXO用户自己管理模式)
Gitee地址:https://gitee.com/BytomBlockchain/bytom
比原链Bytom
2018/08/24
5830
Bytom交易说明(UTXO用户自己管理模式)
1-区块链基础概述
在加密货币应用中,区块链结构的作用就是用作账本,每一个区块都是一页账册,它们相互之间通过哈希值进行连接形成一条完整有序的链表,每个区块的头部哈希是它们的唯一标识。
Ywrby
2022/10/27
1.7K0
1-区块链基础概述
用 Go 构建一个区块链 -- Part 4: 交易(1)
翻译的系列文章我已经放到了 GitHub 上:blockchain-tutorial,后续如有更新都会在 GitHub 上,可能就不在这里同步了。如果想直接运行代码,也可以 clone GitHub 上的教程仓库,进入 src 目录执行 make 即可。
用户1558438
2018/08/23
4470
在区块链上表白——使用C#将一句话放入比特币的区块链上
最近在看区块链和比特币的知识,顺便简单研究了一下BitCoin的脚本语言,发现OP_RETURN这个命令可以在后面放入自己想说的内容,很多侧链啊,公证之类就是利用了这个特性,可以把一句话,或者一个哈希值放在这个命令后面,于是我也想试一试,看看能不能成功。
深蓝studyzy
2022/06/16
8250
在区块链上表白——使用C#将一句话放入比特币的区块链上
用 Go 构建一个区块链 -- Part 5: 地址
翻译的系列文章我已经放到了 GitHub 上:blockchain-tutorial,后续如有更新都会在 GitHub 上,可能就不在这里同步了。如果想直接运行代码,也可以 clone GitHub 上的教程仓库,进入 src 目录执行 make 即可。
用户1558438
2018/08/23
9360
关于 Libra 币交易, 你需要了解的一切...
在上一篇文章中,我们初步探索了 Libra & Move 语言 。在这篇文章中,我们将探讨使用者如何跟 Libra 进行互动。
区块链大本营
2019/07/11
9290
关于 Libra 币交易, 你需要了解的一切...
基于Java语言构建区块链(四)—— 交易(UTXO)
上一篇 文章,我们实现了区块数据的持久化,本篇开始交易环节的实现。交易这一环节是整个比特币系统当中最为关键的一环,并且区块链唯一的目的就是通过安全的、可信的方式来存储交易信息,防止它们创建之后被人恶意篡改。今天我们开始实现交易这一环节,但由于这是一个很大的话题,所以我们分为两部分:第一部分我们将实现区块链交易的基本机制,到第二部分,我们再来研究它的细节。
王维
2018/04/12
2.3K2
基于Java语言构建区块链(四)—— 交易(UTXO)
用NBitcoin进行区块链开发(6):交易签名
比特币交易的签名过程是所有环节中最复杂的步骤之一,下面两篇文章对这个过程有详细的描述。
申龙斌
2019/03/07
1.5K0
用NBitcoin进行区块链开发(6):交易签名
6 个重要模块,带你编写一个基于Golang的区块链公链demo!| 博文精选
今天给大家带来的是基于 Golang 编写的区块链公链 demo,也就是模仿比特币的功能所编写的区块链公链demo。主要应用到了密码学,共识算法,对等网络,区块链防篡改结构等相关知识,并把各个知识点结合到一起,编写成了简单完善的可运行公链demo。
区块链大本营
2020/01/21
1.6K0
6 个重要模块,带你编写一个基于Golang的区块链公链demo!| 博文精选
用 Go 构建一个区块链 -- Part 6: 交易(2)
翻译的系列文章我已经放到了 GitHub 上:blockchain-tutorial,后续如有更新都会在 GitHub 上,可能就不在这里同步了。如果想直接运行代码,也可以 clone GitHub 上的教程仓库,进入 src 目录执行 make 即可。
用户1558438
2018/08/23
3810
比特币核心技术解读
在上一篇文章《区块链基础知识与关键技术》里对区块链的基础知识和关键技术进行了梳理,而比特币是区块链最典型的应用,本文将对比特币核心技术进行解读,如有错漏,欢迎交流指正。
pseudoyu
2023/04/11
1K0
比特币核心技术解读
比特币中对交易进行签名的详细过程
最近在和同事交流我们PalletOne中对UTXO和签名的处理,有些心得,写下此博文。对比特币有点基本概念的都知道,比特币是通过ECDSA数字签名来解锁UTXO中的未花费余额。
深蓝studyzy
2022/06/16
1.6K0
用 Go 构建一个区块链 -- Part 7: 网络
翻译的系列文章我已经放到了 GitHub 上:blockchain-tutorial,后续如有更新都会在 GitHub 上,可能就不在这里同步了。如果想直接运行代码,也可以 clone GitHub 上的教程仓库,进入 src 目录执行 make 即可。
用户1558438
2018/08/23
5430
交易Transaction【区块链生存训练】
日常生活中,我们每天都会与他人进行各种交易,对于“交易”这个概念感觉再熟悉不过了。比如:今天我去吃凉皮,支付给商家5元钱,非常简单吧,通常的交易记录可以是这样的: 付款方收款方金额申龙斌凉皮店老板5 然而,在比特币的区块链里,为了避免双重支付、支持去中心化、挖矿发行货币等,采用了一种完全不同的格式来记录这些交易,通过矿工把这些交易打包并发布在区块链上,它是按币的来源vin和去处vout(或使用条件)来记录的,大概是这样的(注意这是极度简化的常规交易): 输入vin输出vout来源于以前的某笔交易的某项输出支
申龙斌
2018/03/06
1.8K0
交易Transaction【区块链生存训练】
区块链系统化探索:什么是”交易“
在区块链的目最重要的目的就是实现价值的转移。这本质上是信息的发布和存储。例如我要正面我有一百块钱,那么我需要拿出一张 100 块的钞票,这张纸币只不过是一种“我有一百块”这个信息的证明。现在我们都有电子支付,于是“我有一百块”这个信息就变成了微信钱包或支付宝余额宝里面的一个数字,你拿给别人看,他人看到数字就相信你有这个价值。
望月从良
2023/09/02
2150
区块链系统化探索:什么是”交易“
推荐阅读
相关推荐
基于Java语言构建区块链(五)—— 地址(钱包)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验