精华内容
下载资源
问答
  • 简单讲它是连接区块链的一个入口。目前比较成熟的公链,如比特币、以太坊都有很多钱包可以选择。一般钱包需要完全访问你的用户资产,也就是会要求你输入私钥。钱包的作恶成本极低,这也是笔者建议选择开源钱包的原因...

    开发钱包之前,我们需要有以下的预备知识。

    第一,什么是钱包,以及相关的分类。

    本文站在开发者的角度,给读者讲解下怎么样和钱包进行交互,以及如何开发一个钱包。

    我们怎么样理解钱包呢?简单讲它是连接区块链的一个入口。目前比较成熟的公链,如比特币、以太坊都有很多钱包可以选择。一般钱包需要完全访问你的用户资产,也就是会要求你输入私钥。钱包的作恶成本极低,这也是笔者建议选择开源钱包的原因之一。

    129992586_1_20180412031844941

    题图来自: © admin / Delphi White Paper Interpretation / 8855104.com

    第二,需要了解下什么是 RPC、JSON-RPC 以及 JSON。

    远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用,例:Java RMI。[1]

    RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。

    RPC 调用分为以下两种:

    同步调用,客户方等待调用执行完成并返回结果。

    异步调用,客户方调用后不用等待执行结果返回,但依然可以通过回调通知等方式获取返回结果。若客户方不关心调用返回结果,则变成单向异步调用,单向调用不用返回结果。

    异步和同步的区分在于是否等待服务端执行完成并返回结果。

    远程过程调用是一个分布式计算的客户端 - 服务器(Client/Server)的例子,它简单而又广受欢迎。远程过程调用总是由客户端对服务器发出一个执行若干过程请求,并用客户端提供的参数。执行结果将返回给客户端。由于存在各式各样的变体和细节差异,对应地派生了各式远程过程调用协议,而且它们并不互相兼容。其中我们广为使用的是一个叫做 JSON-RPC 的协议。

    JSON-RPC,是一个无状态且轻量级的远程过程调用(RPC)传送协议,其传递内容通过 JSON 为主。相较于一般的 REST 通过网址(如 GET /user)调用远程服务器,JSON-RPC 直接在内容中定义了欲调用的函数名称(如 {“method”: “getUser”}),这也令开发者不会陷于该使用 PUT 或者 PATCH 的问题之中。 本规范主要定义了一些数据结构及其相关的处理规则。它允许运行在基于 Socke

    展开全文
  • blockchain-javaJava实现的一个简易区块链(联盟链)项目,包括加密工具,钱包,P2P 传输,区块同步,POW 共识等基础实现。单节点部署这个很简单, 直接像运行普通的 SpringBoot 项目一样运行就好了,单节点默认使用的 ...

    blockchain-java

    Java实现的一个简易区块链(联盟链)项目,包括加密工具,钱包,P2P 传输,区块同步,POW 共识等基础实现。

    单节点部署

    这个很简单, 直接像运行普通的 SpringBoot 项目一样运行就好了,单节点默认使用的 node1 节点的配置

    多节点部署

    项目默认部署3个节点,创建了3个配置文件 application-{env}.yml, 如果想要部署更多的节点,再创建更多的配置文件就 OK 了。

    使用 idea 部署测试非常简单,按照下面的方法添加多个 springBoot 启动配置。

    5ef282c9a3ddf0a38a2ec05fec77276f.png

    然后分别启动 3 个节点就好了。启动之后节点之间自动连接成 P2P 网络,随后你就可以使用 postman 工具进行测试了,如果没有安装 postman 的话请自行安装,或者和我一样使用 chrome 浏览器的 postman 扩展。

    简单测试

    首先依次启动 node1 - node3 3个节点,由于在启动的时候会自动链接初始化的节点,各自连接成为一个 P2P 的网络,所以被链接的节点没有启动的时候会抛出网络异常,不用管它,等其他节点启动好了之后又会自动连接上的。

    你可以使用 PostMan 工具对上面的 RESTFUL api 进行一一测试。不过从 v1.2 之后我在项目中集成了 swagger2,所以现在更好的测试是直接使用 swagger 的 api ui 页面进行测试: http://localhost:8081/swagger-ui.html

    api.png

    直接点击相应的 api 进行测试就 OK 了。

    Web 测试 API

    API名称

    请求方式

    URL

    生成钱包

    POST

    /api/account/new_account

    查看钱包列表

    GET

    /api/account/list

    获取挖矿账号

    GET

    /api/account/get_miner_address

    启动挖矿

    GET

    /api/chain/mining

    发送交易

    POST

    /api/chain/send_transactions

    查看最后一个区块

    GET

    /api/chain/block/head

    添加节点

    POST

    /api/chain/node/add

    查看节点

    GET

    /api/chain/node/view

    注意:凡是 POST 请求都是使用 RequestBody 的方式传参的, 不是用表单的 form-data 形式, 比如发送交易的参数形式如下:

    {

    "name" : "value",

    "name2" : "value2"

    }

    展开全文
  • $ Pool bas -b 1981344159 -i YOURIPADDRESS -p 123步骤6区块链公链技术有几种将300个HOP token和少量Ropsten ETH转移到与矿池关联的钱包中:$ Pool eth balance -d控制台输出将显示以下类似信息:conf init success...

    文我们将在上一篇文章《使用树莓派(Raspberry Pi)创建分布式HOP流量共识》的基础上介绍HOP矿池我们已经介绍了HOP的概念并创建了一个家庭式分布式流量共识矿机服务矿池(Pool)是矿机(Miner)的付款中心所有矿机均应加入矿池来运行流量共识服务最重要的是从通过Pirate软件从矿池购买流量的用户那里获得TokenPirate是一个与HOP协议连接的DAPP(分布式应用程序)并且是一个数字钱包供用户从矿池中将Token交换到流量计划(即多少GB流量)中使用此流量计划用户可以将所有加入此矿池的矿机连接为分布式流量共识服务器我们假设您已组装并以正确的配置连接了Raspberry Pi 4比特币是什么否则请转到“使用Raspberry Pi创建分布式HOP流量共识服务”以自行设置Raspberry Pi现在让我们开始介绍创建HOP矿池的教程比特币2020以后预测步骤1在帐户主文件夹下创建矿池文件夹从https://docscoin919量化下载hyperorchidorg下载矿池软件或直接将矿池下载到您的树莓派(Raspberry Pi)中:$ curl -o Pool "https://docshyperorchidorg/_media/Pool_arm64"*请注意ARM版本的矿池适用于您的Raspberry Pi如果您的矿池无法运行区块链传销死亡请为矿池分配可执行权限:$ chmod +x Pool步骤2将矿池命令添加到bash配置文件中:vi ~/bashrc将以下内容添加到bash配置文件的最后一行:# User specific environment and startup programsPATH=$PATH

    3a6679e6d7b3a37b3b7a9cbc766f6368.gifHOME/bin:~/hop:~/poolexport PATH重新加载bash配置文件:$ source ~/bashrc步骤3使用以太坊Ropsten测试网络的选项“ -d”启动矿池并创建密码:$ Pool init -d步骤4更改矿池配置:$ vi ~/pool/confjson删除所有信息并将以下内容粘贴到confjson中:"version": "010"中国新闻网区块链"basip": "1981344159""ethereum": "1": "id": 1"apiUrl": "https://mainnetinfuraio/v3/d64d364124684359ace20feae1f9ac20""paymentService": "0x60eB24514eE5D5Be18685b433E5910C3205D085E""token": "0x1999ac2b141E6d5c4e27579b30f842078bc620b3""3": "id": 3"apiUrl": "https://ropsteninfuraio/v3/d64d364124684359ace20feae1f9ac20""paymentService": "0x4291d9Ff189D90Ba875E0fc1Da4D602406DD7D6e""token": "0xAd44c8493dE3FE2B070f33927A315b50Da9a0e25"第5步将您的矿池IP(用myip检查google)注册到HOP协议中:$ Pool bas -b 1981344159 -i YOURIPADDRESS -p 123步骤6区块链公链技术有几种将300个HOP token和少量Ropsten ETH转移到与矿池关联的钱包中:$ Pool eth balance -d控制台输出将显示以下类似信息:conf init success+++++++++++++++++++++++++++++++++++++++++++++++++++++PoolVersion: 010++DebugMode: true++LogLevel: INFO++Token:+++++++++++++++++++++++++++++++++++++++++++++++++++++NetworkID: 3++EthApiUrl: https://ropsteninfuraio/v3/d64d364124684359ace20feae1f9ac20++MicroPaySys: 0x4291d9Ff189D90Ba875E0fc1Da4D602406DD7D6e++Token: 0xAd44c8493dE3FE2B070f33927A315b50Da9a0e25++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++log init success0xa353A767087D9aCab17c3fD941eeD29e166A9982main address:-> 0x0000000000000000000000000000000000000000payer address:-> 0x0000000000000000000000000000000000000000guaranteed token:-> 0official web:->pool's name:->pool's email:->hop balance:-> 200001000000000000000000eth balance:-> 5000000000000000000contract approved:-> 0在该矿池中钱包地址为“ 0xa353A767087D9aCab17c3fD941eeD29e166A9982”请将钱包地址发送至hyperorchidcs@gmailcom以请求HOP Token并访问https://faucetropstenbe/以获取Ropsten ETH步骤7发布您的矿池$ Pool eth reg -d -e "youremail@addresscom" -n &quot

    0fcdf38498ef7a787d9b351c227ccf0c.gifool_Name" -u "https://yoursitecom"打开您的海盗并刷新Android版本中的“流量市场”或iOS版本中的“矿池”步骤8运行矿池$ nohup Pool -d -p 123 2>poollog &步骤9将一个矿机加入您的池中(使用先前文章中的矿机HO82VXn1vnBfLKC6Mx92AKk2kJPJbv4mK

    展开全文
  • Block.javapackage ...import java.io.Serializable;/*** 区块* @author yangjian* @since 18-4-6*/public class Block implements Serializable {/*** 区块 Header*/private BlockHeader head...

    Block.java

    package com.ppblock.blockchain.core;

    import java.io.Serializable;

    /**

    * 区块

    * @author yangjian

    * @since 18-4-6

    */

    public class Block implements Serializable {

    /**

    * 区块 Header

    */

    private BlockHeader header;

    /**

    * 区块 Body

    */

    private BlockBody body;

    public Block(BlockHeader header, BlockBody body) {

    this.header = header;

    this.body = body;

    }

    public Block() {

    }

    public BlockHeader getHeader() {

    return header;

    }

    public void setHeader(BlockHeader header) {

    this.header = header;

    }

    public BlockBody getBody() {

    return body;

    }

    public void setBody(BlockBody body) {

    this.body = body;

    }

    @Override

    public String toString() {

    return "Block{" +

    "header=" + header +

    ", body=" + body.toString() +

    '}';

    }

    }

    BlockBody.java

    package com.ppblock.blockchain.core;

    import java.io.Serializable;

    import java.util.ArrayList;

    import java.util.List;

    /**

    * 区块数据

    * @author yangjian

    * @since 18-4-8

    */

    public class BlockBody implements Serializable {

    /**

    * 区块所包含的交易记录

    */

    private List transactions;

    public BlockBody(List transactions) {

    this.transactions = transactions;

    }

    public BlockBody() {

    this.transactions = new ArrayList<>();

    }

    public List getTransactions() {

    return transactions;

    }

    public void setTransactions(List transactions) {

    this.transactions = transactions;

    }

    /**

    * 追加一笔交易

    * @param transaction

    */

    public void addTransaction(Transaction transaction) {

    transactions.add(transaction);

    }

    @Override

    public String toString() {

    return "BlockBody{" +

    "transactions=" + transactions +

    '}';

    }

    }

    BlockChain.java

    package com.ppblock.blockchain.core;

    import com.google.common.base.Optional;

    import com.google.common.base.Preconditions;

    import com.ppblock.blockchain.crypto.Credentials;

    import com.ppblock.blockchain.crypto.Keys;

    import com.ppblock.blockchain.crypto.Sign;

    import com.ppblock.blockchain.db.DBAccess;

    import com.ppblock.blockchain.enums.TransactionStatusEnum;

    import com.ppblock.blockchain.event.MineBlockEvent;

    import com.ppblock.blockchain.event.SendTransactionEvent;

    import com.ppblock.blockchain.mine.Miner;

    import com.ppblock.blockchain.net.ApplicationContextProvider;

    import com.ppblock.blockchain.net.base.Node;

    import com.ppblock.blockchain.net.client.AppClient;

    import org.slf4j.Logger;

    import org.slf4j.LoggerFactory;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Component;

    import java.math.BigDecimal;

    /**

    * 区块链主类

    * @author yangjian

    * @since 18-4-6

    */

    @Component

    public class BlockChain {

    private static Logger logger = LoggerFactory.getLogger(BlockChain.class);

    @Autowired

    private DBAccess dbAccess;

    @Autowired

    private AppClient appClient;

    @Autowired

    private Miner miner;

    @Autowired

    private TransactionPool transactionPool;

    @Autowired

    private TransactionExecutor executor;

    /**

    * 挖取一个区块

    * @return

    */

    public Block mining() throws Exception {

    Optional lastBlock = getLastBlock();

    Block block = miner.newBlock(lastBlock);

    transactionPool.getTransactions().forEach(e -> block.getBody().addTransaction(e));

    executor.run(block);

    //清空交易池

    transactionPool.clearTransactions();

    //存储区块

    dbAccess.putLastBlockIndex(block.getHeader().getIndex());

    dbAccess.putBlock(block);

    logger.info("Find a New Block, {}", block);

    //触发挖矿事件,并等待其他节点确认区块

    ApplicationContextProvider.publishEvent(new MineBlockEvent(block));

    return block;

    }

    /**

    * 发送交易

    * @param credentials 交易发起者的凭证

    * @param to 交易接收者

    * @param amount

    * @param data 交易附言

    * @return

    * @throws Exception

    */

    public Transaction sendTransaction(Credentials credentials, String to, BigDecimal amount, String data) throws

    Exception {

    //校验付款和收款地址

    Preconditions.checkArgument(to.startsWith("0x"), "收款地址格式不正确");

    Preconditions.checkArgument(!credentials.getAddress().equals(to), "收款地址不能和发送地址相同");

    //构建交易对象

    Transaction transaction = new Transaction(credentials.getAddress(), to, amount);

    transaction.setPublicKey(Keys.publicKeyEncode(credentials.getEcKeyPair().getPublicKey().getEncoded()));

    transaction.setStatus(TransactionStatusEnum.APPENDING);

    transaction.setData(data);

    transaction.setTxHash(transaction.hash());

    //签名

    String sign = Sign.sign(credentials.getEcKeyPair().getPrivateKey(), transaction.toString());

    transaction.setSign(sign);

    //先验证私钥是否正确

    if (!Sign.verify(credentials.getEcKeyPair().getPublicKey(), sign, transaction.toString())) {

    throw new RuntimeException("私钥签名验证失败,非法的私钥");

    }

    //打包数据到交易池

    transactionPool.addTransaction(transaction);

    //触发交易事件,向全网广播交易,并等待确认

    ApplicationContextProvider.publishEvent(new SendTransactionEvent(transaction));

    return transaction;

    }

    /**

    * 获取最后一个区块

    * @return

    */

    public Optional getLastBlock() {

    return dbAccess.getLastBlock();

    }

    /**

    * 添加一个节点

    * @param ip

    * @param port

    * @return

    */

    public void addNode(String ip, int port) throws Exception {

    appClient.addNode(ip, port);

    Node node = new Node(ip, port);

    dbAccess.addNode(node);

    }

    }

    BlockHeader.java

    package com.ppblock.blockchain.core;

    import com.ppblock.blockchain.crypto.Hash;

    import java.io.Serializable;

    import java.math.BigInteger;

    /**

    * 区块头

    * @author yangjian

    * @since 18-4-6

    */

    public class BlockHeader implements Serializable {

    /**

    * 区块高度

    */

    private Integer index;

    /**

    * 难度指标

    */

    private BigInteger difficulty;

    /**

    * PoW 问题的答案

    */

    private Long nonce;

    /**

    * 时间戳

    */

    private Long timestamp;

    /**

    * 区块 Hash

    */

    private String hash;

    /**

    * 上一个区块的 hash 地址

    */

    private String previousHash;

    public BlockHeader(Integer index, String previousHash) {

    this.index = index;

    this.timestamp = System.currentTimeMillis();

    this.previousHash = previousHash;

    }

    public BlockHeader() {

    this.timestamp = System.currentTimeMillis();

    }

    public Integer getIndex() {

    return index;

    }

    public void setIndex(Integer index) {

    this.index = index;

    }

    public BigInteger getDifficulty() {

    return difficulty;

    }

    public void setDifficulty(BigInteger difficulty) {

    this.difficulty = difficulty;

    }

    public Long getNonce() {

    return nonce;

    }

    public void setNonce(Long nonce) {

    this.nonce = nonce;

    }

    public Long getTimestamp() {

    return timestamp;

    }

    public void setTimestamp(Long timestamp) {

    this.timestamp = timestamp;

    }

    public String getPreviousHash() {

    return previousHash;

    }

    public void setPreviousHash(String previousHash) {

    this.previousHash = previousHash;

    }

    public String getHash() {

    return hash;

    }

    public void setHash(String hash) {

    this.hash = hash;

    }

    @Override

    public String toString() {

    return "BlockHeader{" +

    "index=" + index +

    ", difficulty=" + difficulty +

    ", nonce=" + nonce +

    ", timestamp=" + timestamp +

    ", hash='" + hash + '\'' +

    ", previousHash='" + previousHash + '\'' +

    '}';

    }

    /**

    * 获取区块头的 hash 值

    * @return

    */

    public String hash() {

    return Hash.sha3("BlockHeader{" +

    "index=" + index +

    ", difficulty=" + difficulty +

    ", nonce=" + nonce +

    ", timestamp=" + timestamp +

    ", previousHash='" + previousHash + '\'' +

    '}');

    }

    }

    Transaction.java

    package com.ppblock.blockchain.core;

    import com.ppblock.blockchain.crypto.Hash;

    import com.ppblock.blockchain.enums.TransactionStatusEnum;

    import java.math.BigDecimal;

    /**

    * 交易对象

    * @author yangjian

    * @since 18-4-6

    */

    public class Transaction {

    /**

    * 付款人地址

    */

    private String from;

    /**

    * 付款人签名

    */

    private String sign;

    /**

    * 收款人地址

    */

    private String to;

    /**

    * 收款人公钥

    */

    private String publicKey;

    /**

    * 交易金额

    */

    private BigDecimal amount;

    /**

    * 交易时间戳

    */

    private Long timestamp;

    /**

    * 交易 Hash 值

    */

    private String txHash;

    /**

    * 交易状态

    */

    private TransactionStatusEnum status = TransactionStatusEnum.SUCCESS;

    /**

    * 交易错误信息

    */

    private String errorMessage;

    /**

    * 附加数据

    */

    private String data;

    public Transaction(String from, String to, BigDecimal amount) {

    this.from = from;

    this.to = to;

    this.amount = amount;

    this.timestamp = System.currentTimeMillis();

    }

    public Transaction() {

    this.timestamp = System.currentTimeMillis();

    }

    public String getFrom() {

    return from;

    }

    public void setFrom(String from) {

    this.from = from;

    }

    public String getSign() {

    return sign;

    }

    public void setSign(String sign) {

    this.sign = sign;

    }

    public String getTo() {

    return to;

    }

    public void setTo(String to) {

    this.to = to;

    }

    public String getPublicKey() {

    return publicKey;

    }

    public void setPublicKey(String publicKey) {

    this.publicKey = publicKey;

    }

    public BigDecimal getAmount() {

    return amount;

    }

    public void setAmount(BigDecimal amount) {

    this.amount = amount;

    }

    public Long getTimestamp() {

    return timestamp;

    }

    public void setTimestamp(Long timestamp) {

    this.timestamp = timestamp;

    }

    public String getTxHash() {

    return txHash;

    }

    public void setTxHash(String txHash) {

    this.txHash = txHash;

    }

    public TransactionStatusEnum getStatus() {

    return status;

    }

    public void setStatus(TransactionStatusEnum status) {

    this.status = status;

    }

    public String getErrorMessage() {

    return errorMessage;

    }

    public void setErrorMessage(String errorMessage) {

    this.errorMessage = errorMessage;

    }

    public String getData() {

    return data;

    }

    public void setData(String data) {

    this.data = data;

    }

    /**

    * 计算交易信息的Hash值

    * @return

    */

    public String hash() {

    return Hash.sha3(this.toString());

    }

    @Override

    public String toString() {

    return "Transaction{" +

    "from='" + from + '\'' +

    ", to='" + to + '\'' +

    ", publicKey=" + publicKey +

    ", amount=" + amount +

    ", timestamp=" + timestamp +

    ", data='" + data + '\'' +

    '}';

    }

    }

    TransactionExecutor.java

    package com.ppblock.blockchain.core;

    import com.google.common.base.Optional;

    import com.ppblock.blockchain.account.Account;

    import com.ppblock.blockchain.crypto.Keys;

    import com.ppblock.blockchain.crypto.Sign;

    import com.ppblock.blockchain.db.DBAccess;

    import com.ppblock.blockchain.enums.TransactionStatusEnum;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Component;

    import java.math.BigDecimal;

    /**

    * 交易执行器

    * @author yangjian

    * @since 18-4-23

    */

    @Component

    public class TransactionExecutor {

    @Autowired

    private DBAccess dbAccess;

    @Autowired

    private TransactionPool transactionPool;

    /**

    * 执行区块中的交易

    * @param block

    */

    public void run(Block block) throws Exception {

    for (Transaction transaction : block.getBody().getTransactions()) {

    synchronized (this) {

    Optional recipient = dbAccess.getAccount(transaction.getTo());

    //如果收款地址账户不存在,则创建一个新账户

    if (!recipient.isPresent()) {

    recipient = Optional.of(new Account(transaction.getTo(), BigDecimal.ZERO));

    }

    //挖矿奖励

    if (null == transaction.getFrom()) {

    recipient.get().setBalance(recipient.get().getBalance().add(transaction.getAmount()));

    dbAccess.putAccount(recipient.get());

    continue;

    }

    //账户转账

    Optional sender = dbAccess.getAccount(transaction.getFrom());

    //验证签名

    boolean verify = Sign.verify(

    Keys.publicKeyDecode(transaction.getPublicKey()),

    transaction.getSign(),

    transaction.toString());

    if (!verify) {

    transaction.setStatus(TransactionStatusEnum.FAIL);

    transaction.setErrorMessage("交易签名错误");

    continue;

    }

    //验证账户余额

    if (sender.get().getBalance().compareTo(transaction.getAmount()) == -1) {

    transaction.setStatus(TransactionStatusEnum.FAIL);

    transaction.setErrorMessage("账户余额不足");

    continue;

    }

    //执行转账操作,更新账户余额

    sender.get().setBalance(sender.get().getBalance().subtract(transaction.getAmount()));

    recipient.get().setBalance(recipient.get().getBalance().add(transaction.getAmount()));

    dbAccess.putAccount(sender.get());

    dbAccess.putAccount(recipient.get());

    }//end synchronize

    }// end for

    //清空交易池

    transactionPool.clearTransactions();

    }

    }

    TransactionPool.java

    package com.ppblock.blockchain.core;

    import com.google.common.base.Objects;

    import org.springframework.stereotype.Component;

    import java.util.ArrayList;

    import java.util.List;

    /**

    * 交易池

    * @author yangjian

    * @since 18-4-23

    */

    @Component

    public class TransactionPool {

    private List transactions = new ArrayList<>();

    /**

    * 添加交易

    * @param transaction

    */

    public void addTransaction(Transaction transaction) {

    boolean exists = false;

    //检验交易是否存在

    for (Transaction tx : this.transactions) {

    if (Objects.equal(tx.getTxHash(), transaction.getTxHash())) {

    exists = true;

    }

    }

    if (!exists) {

    this.transactions.add(transaction);

    }

    }

    public List getTransactions() {

    return transactions;

    }

    /**

    * 清空交易池

    */

    public void clearTransactions() {

    this.transactions.clear();

    }

    }

    展开全文
  • 区块链钱包—BTC Java版离线签名交易

    千次阅读 热门讨论 2019-06-14 18:36:47
    由于已经不从事区块链相关项目,对疑惑的小伙伴提供一些帮助~~ 对于离线交易不做过多解释~,说白了就是拿上一笔未发出交易记录进行私钥的签名然后广播到链上。 主要是对区块链离线交易进行utxo上链。 废话不多说 ...
  • 区块链钱包实现源码,Java语言版本,有点类似imtoken钱包,基本的业务框架都已经实现,适合初学者上手练习。
  • Java简易区块链钱包源码ppblock V1.0

    千次阅读 2018-08-11 17:31:44
    ppblock区块链 Java 的简易实现版,自学了一段时间的区块链理论知识,自己尝试着写一个具有钱包雏形的区块链项目,开源出来, 供像我一样想开发区块链又不知从何下手初学者参考。目前大部分区块链从业者都是从事 ...
  • 区块链钱包开发之Omni USDT Java版本离线签名

    千次阅读 多人点赞 2018-12-28 17:44:38
    从事区块链钱包方向已经快一年了,一直处于研究方向,没时间分享经验,趁着这次机会就分享一下大家比较头疼的基于Omni协议上USDT有坑的地方,以及如何离线签名。 正文 1.转usdt的关键 我们先要知道BTC和USDT之间...
  • 一个 Bitcoin 钱包包含了一系列的密钥对,每个密钥对都是由一对公钥(public key)和私钥(private key)组成。私钥(k)通常是随机选出的一串数字串,之后我们就可以通过椭圆曲线密码学(ECC)算法来产生一个公钥(K),然后...
  • 由于已经不从事区块链相关项目,对疑惑的小伙伴提供一些帮助~~对于离线交易不做过多解释~,说白了就是拿上一笔未发出交易记录进行私钥的签名然后广播到链上。主要是对区块链离线交易进行utxo上链。废话不多说 ,直接...
  • 一个 Bitcoin 钱包包含了一系列的密钥对,每个密钥对都是由一对公钥(public key)和私钥(private key)组成。私钥(k)通常是随机选出的一串数字串,之后我们就可以通过椭圆曲线密码学(ECC)算法来产生一个公钥(K),然后...
  • 区块链钱包—BTC离线签名交易(java)

    千次阅读 2019-06-04 03:47:40
    由于已经不从事区块链相关项目,对疑惑的小伙伴提供一些帮助~~对于离线交易不做过多解释~,说白了就是拿上一笔未发出交易记录进行私钥的签名然后广播到链上。主要是对区块链离线交易进行utxo上链。废话不多说 ,直接...
  • 区块链钱包开发之BCH(BSV)Java版本离线签名

    千次阅读 热门讨论 2019-03-08 12:41:19
    大家好,我是凉凉,距离上一篇博客有一段时间了,中间也一直在做其他事情,没时间更新博客,现在就来说下BCH(BSV)的java版本的离线签名,我发这篇博客的原因也是因为之前在对接BCH(BSV)的时候没有找到什么好的资料,后面...
  • 环境要求我们将使用Tezos区块链。为了使我们的Android java代码与现有的、部署的智能合约交互,我们需要使用TezosRio的TeZOSJ库。这个库有两个版本,一个是专门为使用EclipseIDE制作的通用Java应用程序编写的...
  • 软件简介ppblock区块链 Java 的简易实现版,自学了一段时间的区块链理论知识,自己尝试着写一个具有钱包雏形的区块链项目,开源出来,供像我一样想开发区块链又不知从何下手初学者参考。目前大部分区块链从业者都是...
  • 这步就很重要的了,找到dome中的io.neow3j.examples.ransactions.CreateRawTransactionMultiSig.java,这个就是签名的东西了,就是我在客服端签名转账的java内容了....这个是个多重签名(这个就不多做解释了百度哈)...
  • blockchain-javaJava实现的一个简易区块链(联盟链)项目,包括加密工具,钱包,P2P 传输,区块同步,POW 共识等基础实现。单节点部署这个很简单, 直接像运行普通的 SpringBoot 项目一样运行就好了,单节点默认使用的 ...
  • blockchain-javaJava实现的一个简易区块链(联盟链)项目,包括加密工具,钱包,P2P 传输,区块同步,POW 共识等基础实现。单节点部署这个很简单, 直接像运行普通的 SpringBoot 项目一样运行就好了,单节点默认使用的 ...
  • 涉及内容:注意,学习此视频必须有一定基础的同学区块链相关知识、钱包相关知识、p2p相关知识、uniapp相关知识01前言02成果展示03前言区块链概念和六层模型介绍04翻译一个带币的js简单例子原理介绍05区块链...
  • Javacard----区块链电子钱包

    千次阅读 2018-06-14 20:45:58
    总体需求:建立一个比特币钱包程序,能够完成获取学号、获取学号、挖矿、生成钱包这四个功能。 (1)获取学号:使用10个ASCII码表示学号,由卡片向终端返还。 (2)获取姓名:使用GB2312编码表示姓名,由卡片向...
  • 大家好,我们都听说过比特币,以太坊或其他加密货币,我们周围的新闻都是时髦的名字,但是,我们作为Java开发人员知道如何轻松地与这些区块链技术进行交互吗?以下是目前可用于利用区块链开发的前3名的Java项目。该...
  • blockchain-java区块链 Java 的简易实现版,自学了一段时间的区块链理论知识,自己尝试着写一个具有钱包雏形的区块链项目,开源出来,供像我一样想开发区块链又不知从何下手初学者参考,也希望大牛们能够给点指导。...
  • 前言开发前看一下EOS白皮书最好,先了解EOS的架构及相关...(本篇文章需要本地启动一个钱包服务keosd或者eosio. 最新一篇文章采用离线签名无需启动服务https://blog.csdn.net/liu1765686161/article/details/833088...
  • blockchain-java区块链钱包 Java 的简易实现版,自学了一段时间的区块链理论知识,自己尝试着写一个具有钱包雏形的区块链项目,开源出来,供像我一样想开发区块链又不知从何下手初学者参考。目前大部分区块链从业者...
  • 在处理项目时,用Java Connector for EOS区块链编写:创建钱包创建帐户创建交易创建签名交易在帐户之间转移代币我遇到了各种和运行本地EOS节点需要遵循的基本步骤。这个小指南纯粹是为了帮助你启动和运行自己的EOS...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 154
精华内容 61
关键字:

区块链钱包java

java 订阅