基于Crypto++密码库的ECIES和ECDSA算法的联合使用

Auteur:GX
CSDN:GuoXuan_CHN

#include <iostream>

#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include "hex.h"
#include "filters.h"

#ifndef ECC_ENCRYPTION_ALGORITHM_H_
#define ECC_ENCRYPTION_ALGORITHM_H_

#include<string>

class EccEncryption
{
public:
    /// This method is used to generate keys for ECC encryption algorithm
    ///
    ///  \param[in]  uiKeySize, length of key
    /// \param[out]  sPrivateKey, private key
    /// \param[out]  sPublicKey, public key
    void GenerateEccKeys(unsigned int uiKeySize, std::string& sPrivateKey, std::string& sPublicKey);

    /// This method is used to encrypt the input message using public key
    ///
    ///  \param[in]  sPublicKey, public key generated by the first method
    /// \param[out]  sMsgToEncrypt, message to encryppt
    /// \return  the message encrypted using the input public key
    std::string Encrypt(const std::string& sPublicKey, const std::string& sMsgToEncrypt);

    /// This method is used to decrypt the input message using private key
    ///
    /// \param[in] sPrivateKey, private key used to decrypt the cipher text
    /// \param[in] sMsgToDecrypt, cipher text used to decrypt to get the plain text
    /// \return decrypted plain text
    std::string Decrypt(const std::string& sPrivateKey, const std::string& sMsgToDecrytp);
};
#endif

void EccEncryption::GenerateEccKeys(unsigned int uiKeySize, std::string& sPrivateKey, std::string& sPublicKey)
{
    using namespace CryptoPP;
    // Random pool, the second parameter is the length of key
    // 随机数池,第二个参数是生成密钥的长
    AutoSeededRandomPool rnd(false, 256);

    ECIES<ECP>::PrivateKey  privateKey;
    ECIES<ECP>::PublicKey   publicKey;

    // Generate private key
    privateKey.Initialize(rnd, ASN1::secp256r1());
    // Generate public key using private key
    privateKey.MakePublicKey(publicKey);

    ECIES<ECP>::Encryptor encryptor(publicKey);
    HexEncoder pubEncoder(new StringSink(sPublicKey));
    publicKey.DEREncode(pubEncoder);
    pubEncoder.MessageEnd();

    ECIES<ECP>::Decryptor decryptor(privateKey);
    HexEncoder prvEncoder(new StringSink(sPrivateKey));
    privateKey.DEREncode(prvEncoder);
    prvEncoder.MessageEnd();
}

std::string EccEncryption::Encrypt(const std::string& sPublicKey, const std::string& sMsgToEncrypt)
{
    using namespace CryptoPP;
    // If to save the keys into a file, FileSource should be replace StringSource
    StringSource pubString(sPublicKey, true, new HexDecoder);
    ECIES<ECP>::Encryptor encryptor(pubString);

    // Calculate the length of cipher text
    size_t uiCipherTextSize = encryptor.CiphertextLength(sMsgToEncrypt.size());
    std::string sCipherText;
    sCipherText.resize(uiCipherTextSize);
    RandomPool rnd;
    encryptor.Encrypt(rnd, (byte*)(sMsgToEncrypt.c_str()), sMsgToEncrypt.size(), (byte*)(sCipherText.data()));
    return sCipherText;
}

std::string EccEncryption::Decrypt(const std::string& sPrivateKey, const std::string& sMsgToDecrytp)
{
    using namespace CryptoPP;
    StringSource privString(sPrivateKey, true, new HexDecoder);
    ECIES<ECP>::Decryptor decryptor(privString);

    auto sPlainTextLen = decryptor.MaxPlaintextLength(sMsgToDecrytp.size());
    std::string sDecryText;
    sDecryText.resize(sPlainTextLen);
    RandomPool rnd;
    decryptor.Decrypt(rnd, (byte*)sMsgToDecrytp.c_str(), sMsgToDecrytp.size(), (byte*)sDecryText.data());
    return sDecryText;
}

int main()
{
    std::string sStrToTest = std::string("Hello world. This is an example of Ecc encryption algorithm of Crypto++ open source library.");
    EccEncryption ecc;
    std::string sPrivateKey, sPublicKey;
    ecc.GenerateEccKeys(1024, sPrivateKey, sPublicKey);

    std::cout << "Generated private key is : "<< std::endl;
    std::cout << sPrivateKey << std::endl;
    std::cout << "***********************************************************" << std::endl;

    std::cout << "Generated public key is : "<< std::endl;
    std::cout << sPublicKey << std::endl;
    std::cout << "***********************************************************" << std::endl;

    std::cout << "The message to be encrypted is : " << std::endl;
    std::cout << sStrToTest << std::endl;
    std::cout << "***********************************************************" << std::endl;

    std::string sEncryptResult = ecc.Encrypt(sPublicKey, sStrToTest);
    std::cout << "The result of encrypt is : " << std::endl;
    std::cout << sEncryptResult << std::endl;
    std::cout << "***********************************************************" << std::endl;

    std::string sDecryptResult = ecc.Decrypt(sPrivateKey, sEncryptResult);
    std::cout << "The result of decrypt is : " << std::endl;
    std::cout << sDecryptResult << std::endl;
    std::cout << "***********************************************************" << std::endl;

    return 0;
}

ECIES-ECSDSA联合使用Demo

/*
auteur:GX
CSDN:GuoXuan_CHN
*/
#include <fstream>
#include <string>
#include <iostream>

#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include "hex.h"
#include "filters.h"
#include "des.h"

using namespace std;

 CryptoPP::ECIES<CryptoPP::ECP>::PrivateKey  ePrivateKey;
 CryptoPP::ECIES<CryptoPP::ECP>::PublicKey   ePublicKey;
string sPrivateKey, sPublicKey;


void GenerateEccKeys()
{
    using namespace CryptoPP;

    // Random pool, the second parameter is the length of key
    // 随机数池,第二个参数是生成密钥的长
    AutoSeededRandomPool rnd(false, 256);


    // Generate private key
    // 生成私钥
    ePrivateKey.Initialize(rnd, ASN1::secp256r1());

    // Generate public key using private key
    // 用私钥生成密钥
    ePrivateKey.MakePublicKey(ePublicKey);


    HexEncoder pubEncoder(new StringSink(sPublicKey));
    ePublicKey.DEREncode(pubEncoder);
    pubEncoder.MessageEnd();

    HexEncoder prvEncoder(new StringSink(sPrivateKey));
    ePrivateKey.DEREncode(prvEncoder);
    prvEncoder.MessageEnd();
}

string signe (string message)
{
    std::string signature="";

    //数字签名过程
    CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::PrivateKey privateKey;
    std::string exp = sPrivateKey.substr(70);

    CryptoPP::HexDecoder decoder;
    decoder.Put((CryptoPP::byte *)&exp[0], exp.size());
    decoder.MessageEnd();

    CryptoPP::Integer x;
    x.Decode(decoder, decoder.MaxRetrievable());

    privateKey.Initialize(CryptoPP::ASN1::secp256r1(), x);

    CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::Signer signer( privateKey );

    CryptoPP::AutoSeededRandomPool prng;

    //签名结果
    signature = "";

    CryptoPP::StringSource s( message, true /*pump all*/,
                             new  CryptoPP::SignerFilter( prng,
                                                         signer,
                                                         new  CryptoPP::StringSink( signature )
                                                         ) // SignerFilter
                             ); // StringSource

    return signature;
    //签名过程结束
}

bool VerifierSignature(string signature,string message)
{
    std::string pt="";

    //验签过程
    CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::PublicKey publicKey;

    pt = sPublicKey.substr(54);

    CryptoPP::HexDecoder decoder;
    decoder.Put((CryptoPP::byte *)&pt[0], pt.size());
    decoder.MessageEnd();

    CryptoPP::ECP::Point q;
    size_t len = decoder.MaxRetrievable();

    q.identity = false;
    q.x.Decode(decoder, len/2);
    q.y.Decode(decoder, len/2);

    publicKey.Initialize( CryptoPP::ASN1::secp256r1(), q );

    CryptoPP::ECDSA<CryptoPP::ECP,CryptoPP::SHA1>::Verifier verifier(publicKey);

    // Result of the verification process
    bool result = false;

    CryptoPP::StringSource ss( signature+message, true /*pump all*/,
                              new CryptoPP::SignatureVerificationFilter(
                                                                        verifier,
                                                                        new CryptoPP::ArraySink((CryptoPP::byte *)&result, sizeof(result) )
                                                                        )
                              );
    return result;
}

int main()
{
    std::string message = "Yoda said, Do or do not. There is no try.";
    std::string signature="";
    bool result = false;

    GenerateEccKeys();

    signature = signe (message);

    result = VerifierSignature(signature,message);
    cout << "****** tester la bon*****" << endl;
    cout << result << endl;

    result = VerifierSignature(signature,"1234567890");
    cout << "****** tester la mauvais*****" << endl;
    cout << result << endl;

}
10/08/2018 19:01 下午 posted in  Bitcoin

iOS - ECC椭圆曲线、ECDSA签名验签和ECIES加解密

前言

ECC英文全称"Ellipse Curve Cryptography",与传统的基于大质数因子分解困难性的加密方法不同,ECC通过椭圆曲线方程式的性质产生密钥

ECC164位的密钥产生一个安全级,相当于RSA 1024位密钥提供的保密强度,而且计算量较小,处理速度更快,存储空间和传输带宽占用较少。目前我国居民二代身份证正在使用 256 位的椭圆曲线密码,虚拟货币比特币也选择ECC作为加密算法。

加密

基于这个秘密值,用来对Alice和Bob之间的报文进行加密的实际方法是适应以前的,最初是在其他组中描述使用的离散对数密码系统。这些系统包括:

Diffie-Hellman—ECDH

MQV—ECMQV

ElGamal discrete log cryptosystem—ECElGamal

数字签名算法—ECDSA

对于ECC系统来说,完成运行系统所必须的群操作比同样大小的因数分解系统或模整数离散对数系统要慢。不过,ECC系统的拥护者相信ECDLP问题比DLP或因数分解问题要难的多,并且因此使用ECC能用小的多的密钥长度来提供同等的安全,在这方面来说它确实比例如RSA之类的更快。到目前为止已经公布的结果趋于支持这个结论,不过一些专家表示怀疑。

ECC被广泛认为是在给定密钥长度的情况下,最强大的非对称算法,因此在对带宽要求十分紧的连接中会十分有用。

优点

安全性高

有研究表示160位的椭圆密钥与1024位的RSA密钥安全性相同。

处理速度快

在私钥的加密解密速度上,ecc算法比RSA、DSA速度更快。
存储空间占用小。
带宽要求低。
以上为ECC椭圆曲线算法需要了解的基本知识,摘自强大的百科度娘。

iOS-ECC

关于ECC,苹果支持以下算法:

PKG:

curves P-224, P-256, P-384, P-521

PKV:

curves P-224, P-256, P-384, P-521

Signature Generation:

curves P-224, P-256, P-384, P-521

using (SHA-224, SHA-256, SHA384, SHA512)

Signature Verification:

curves P-224, P-256, P-384, P-521

using (SHA-1, SHA-224, SHA-256, SHA384, SHA512)

采用的都是NIST标准和规范。但是苹果官方API仅为开发者提供了椭圆曲线P-256的256位EC密钥。由于苹果SEP硬件提供的保护机制,私钥会直接以keychain的形式截留在SEP中,不能提取,也不能从外部导入,只能通过引用使用。

ECDSA

椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟,下面是关于ECDSA的API调用。

1、创建ECC椭圆曲线的keychain属性,属性设置具体可以根据自己需要,获取ECC私钥。

sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,  
                                             kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,  
                                             // kSecAccessControlTouchIDAny |  
                                             kSecAccessControlPrivateKeyUsage, &error);  
    
 // Create parameters dictionary for key generation.  
 NSDictionary *parameters = @{  
                              (id)kSecAttrTokenID: (id)kSecAttrTokenIDSecureEnclave,  
                              (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom,  
                              (id)kSecAttrKeySizeInBits: @256,  
                              (id)kSecAttrLabel: @"my-se-key",  
                              (id)kSecPrivateKeyAttrs: @{  
                                      (id)kSecAttrAccessControl: (__bridge_transfer id)sacObject,  
                                      (id)kSecAttrIsPermanent: @YES,  
                                      }  
                              };
NSError *gen_error = nil;
//根据参数生成私钥
id privateKey = CFBridgingRelease(SecKeyCreateRandomKey((__bridge CFDictionaryRef)parameters, (voidvoid *)&gen_error));
2.使用私钥提取公钥,并用于签名。

//根据keychain的属性查找ECC私钥,并获取私钥引用。

NSDictionary *params = @{
 
(id)kSecClass: (id)kSecClassKey, (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @256, (id)kSecAttrLabel: @"my-se-key", (id)kSecReturnRef: @YES, (id)kSecUseOperationPrompt: @"Authenticate to sign data" };

SecKeyRef privateKey;  
      OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)params, (CFTypeRef *)&privateKey);
     

3.签名

NSError *error;  
NSData *dataToSign = [@"我是签名内容" dataUsingEncoding:NSUTF8StringEncoding];  
NSData *signature = CFBridgingRelease(SecKeyCreateSignature(privateKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)dataToSign, (voidvoid *)&error));

对于kSecKeyAlgorithmECDSASignatureMessageX962SHA256签名算法,官方还给了:SHA1、SHA224、SHA384、SHA512用于EC密钥摘要。可以自己需求选择签名对应的摘要算法。API的名字也很明确的给了这里执行的标准规范为X9.62。

4.验签

//提取公钥,进行验签,验签选择的算法必须与签名时的算法一致。
 
id publicKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)privateKey));
 
Boolean verified = SecKeyVerifySignature((SecKeyRef)publicKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)dataToSign, (CFDataRef)signature, (void *)&error); if (verified == 1) { message = [NSString stringWithFormat:@"signature:%@ verified:%@ error:%@", signature, @"验签成功", error]; }else{ message = [NSString stringWithFormat:@"signature:%@ verified:%@ error:%@", signature, @"验签失败", error]; }

##ECIES
校验密钥是否和算法是否匹配,只有都符合条件了才能用于加密。

SecKeyAlgorithm algorithm = kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM;  
BOOL canEncrypt = SecKeyIsAlgorithmSupported((SecKeyRef)publicKey,kSecKeyOperationTypeEncrypt, algorithm);

加密

CFErrorRef error = NULL;  
   cipherText = (NSData*)CFBridgingRelease(      // ARC takes ownership  
                                           SecKeyCreateEncryptedData(publicKey,  
                                                                     algorithm,  
                                                                     (__bridge CFDataRef)encryptionData,&error));

encryptionData为要加密的数据,这里提示一下:

As an additional check before encrypting, because asymmetric encryption restricts the length of the data that you can encrypt, verify that the data is short enough. For this particular algorithm, the plain text data must be 130 bytes smaller than the key’s block size, as reported by SecKeyGetBlockSize. You therefore further condition the proceedings on a length test:

NSData* plainText = ;
canEncrypt &= ([plainText length] < (SecKeyGetBlockSize(publicKey)-130));

官方API描述,明文数据要比密钥块小130个字节。

解密

CFErrorRef error = NULL;  
    clearText = (NSData*)CFBridgingRelease(       // ARC takes ownership  
                                           SecKeyCreateDecryptedData(private,  
                                                                     algorithm,  
                                                                     (__bridge CFDataRef)cipherText,

https://developer.virgilsecurity.com/docs/sdk-and-tools

https://medium.com/@edisonlo/objective-c-digital-signature-signing-and-verification-with-pem-der-or-base64-string-aff4c0a7f805

https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html

https://forums.developer.apple.com/thread/87758

PUBLIC_KEY = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAESJCvH4lEoGgLof637UGdAYHwFW0GddD/DbVu8yFVTt5Zq+kkftDpQDelSnhmmbr9v+ZsIESINctknP3LTbeLIg==";
PRIVATE_KEY = "MIGNAgEAMBAGByqGSM49AgEGBSuBBAAKBHYwdAIBAQQgi5h75Y80gEeJQQZ6zq7zjT9a11lyLhf9kF/ItIGFDHCgBwYFK4EEAAqhRANCAARIkK8fiUSgaAuh/rftQZ0BgfAVbQZ10P8NtW7zIVVO3lmr6SR+0OlAN6VKeGaZuv2/5mwgRIg1y2Sc/ctNt4si";

09/30/2018 16:36 下午 posted in  Bitcoin

区块链中,交易被如何打包进区块

R:https://www.tangshuang.net/4097.html

大部分材料都详细分析了挖矿过程,介绍了区块是如何产生的。然而,区块的产生并不是区块链的最终目的,保存交易信息才是区块链的最终目的。所以,更重要的一点是要理解,交易信息是如何被打包进区块链的。

##输入和输出

一个交易在系统里被输入和输出表示。输入是指这笔交易所要进行转移的币来自之前的哪些输出。输出是指这些币将会被发送给哪些地址。在区块链上记账,不是告诉你一个账号现在有多少钱,而是告诉你这个账号当前得到了哪些输出。比如一个地址xsw0923sdfew2389dsfw它的相关记录里面,有A、B、C三个输出的目标地址是它,那么它实际上的余额就是这三个输出的金额的总和。

但是现在这个地址的用户要转账了,转账过程不是直接从总和数字中取出一部分进行转移,而是分别从A、B、C三个输出中取出部分或全部,加起来为想要转移的总和的币,进行转移。这个“取出”过程中,A、B、C就变成了输入,转账目标记录才是这次交易的输出。

这样的设计,保证了区块链中的钱从哪里来,到哪里去,一清二楚,绝不含糊。跟会计做账一样,花一笔钱,不单单要记录它花到哪里去了,还要记录这笔钱是从哪里来的,整个资金链是可追溯的,这也保证了交易不可伪造,资金既不会凭空消失,也不会无中生有。

##hash

将交易加入到区块里面需要涉及三个hash,一个是交易本身的hash,另一个是当前这个区块所有交易的merkle hash root,还有一个就是区块hash。

上面已经说过输入与输出了,一个交易可能包含多个输入输出,通过将这些输入输出信息进行排列并进行hash运算,就得到一个交易的唯一hash值。

一个区块里面包含了多个交易,包括挖矿奖励交易,这些交易都被通过一个merkle运算,得到一个hash root所包含,对于merkle可以阅读《区块链如何运用merkle tree验证交易真实性》了解。

区块都hash运算里面,merkle hash root作为一个参数,因此,所有交易的信息都体现在了一个区块的hash里面。

Q:
挖矿成功产生的hash值代表的区块的所有信息,应该包含了交易信息。为了保证区块未被篡改。在区块接收到上一个区块广播出的hash验证合理后,开始计算下一块hash,根据情况加入收到的交易信息。直到完成POW证明。代表区块已经产生(挖矿成功)

##挖矿

挖矿过程就是计算上述区块hash的过程,几乎所有的机器都可以挖矿成功。关键在于谁先挖到矿,因为当一台机器挖矿成功就向网络广播,其他挖矿在对这个hash进行校验之后,就停止自己的挖矿,开始基于这个区块挖新的矿。而每一个被挖到区块中记录的第一笔交易是给挖到这个区块的矿工自己的奖励金,所以抢到第一个挖矿成功名额对于矿工来说至关重要。

前面说过,计算区块hash过程里面,会以区块包含的交易的merkle hash root作为计算的一个参数,因此,挖矿时,矿工会事先从自己本地的交易信息里面提炼出merkle hash root,也就是说,在挖矿之前,对于当前这个矿工来说,新区块会包含哪些交易就已经确定好了的。关于这个过程,可以阅读《Merkle Tree》。

##打包交易记录

挖矿成功之后,矿工需要将完整的区块向网络广播,这个时候,这个区块里面就打包了所有上述对应的交易。

现在有三个问题:

在打包开始之前,这些交易记录是以什么方式存在于网络?
打包是否会把所有交易记录打包进区块?怎么可能保证所有交易都不被遗漏?
如何防止矿工伪造交易?将伪造的交易打包进区块?
##手续费

这里需要知道另外一个概念,即“手续费”。手续费是发起交易的节点决定给的,和小费性质一样。比如A打算转给B0.5个BTC,A手上有一个完整的(来自一个输入)BTC,这时A将这1BTC作为输入,输出包含两条,一条是给B0.5BTC,另一条是给自己0.49BTC(这个过程叫“找零”)。那么这个交易中就有0.01BTC是消失了,消失了的BTC将作为小费奖赏给矿工。

现在我们把自己的角色转换为矿工,当我们从自己的内存中收集所有交易,准备打包区块时,发现这里有一条交易有0.01BTC的小费,于是我把它作为本次打包优先考虑的交易记录。由于每个区块的大小限制在1M左右,所有我只选了那些给小费的交易打包进这次区块。而那些未给交易费的交易,在优先考虑完这些有交易费的交易之后,我才会考虑把它们加进来。

这也就是为什么有些交易被确认很快,有些交易被确认很慢。

##确认

“确认”这个概念也要解释一下,一个区块产生之后,它不是立即可信的,网络上的节点总是相信最长的区块链,当一条交易记录被打包进一个区块之后,就有了一个确认,而这个区块所在的链后面被再加入一个区块,就是第二个确认,如此下去,一个交易有了6个确认,我们就认为这个交易已经确定了,会被永远记录在区块链中。为什么是6个确认呢?因为每一个确认就是一个挖矿过程,都需要提供非常严格的计算,因此,这6个区块被同一个矿工创建的可能性微乎其微(可以说是不可能),因此矿工伪造交易也基本不可能。

由于比特币的区块平均产生时间是10分钟,所以一个交易要1小时左右才能保证成功(最快),不过也不是所有的系统都这样认为,有些网站在接受比特币支付时,认为4个确认就可以给客户发货了。如果不幸这个交易在创建的时候,没有被打包进最近的那个区块,那就要延迟10分钟,如此下去,如果后面过了好几个区块,交易都没有被打包进区块链,那就悲剧了。

##广播交易

不过也不用着急,比特币系统中只留给了这种优先级高的交易50k的存储空间,即使你没有给交易费,也可能在24小时内被打包进区块。不过也不一定,有些交易可能永远都进不了区块,因为矿工是从自己都内存中获取自己暂存的交易信息,一旦这些内存被释放,那么这些交易信息就会被清空。为了解决这个问题,比特币钱包需要不断对自己发起的交易进行检查,如果发现没有被打包进最新的区块,就要对网络广播,这样,这个交易就会在网络里不断被提起,矿工又可以把这笔交易写进自己的内存里暂时放着,等到下次打包区块时,选择是否把它打包进去。

Q:
是否将某个交易打包进挖的那个区块确实是矿工自己决定的,所以才会有51%攻击,当你手上控制了超过51%的算力,你就决定了整个网络哪些交易可以被加入到区块链,哪些可能永远都不会。
这和“只保留50K”并不矛盾,那50K是给有手续费的交易的,即使你机器里面还有其他包含了手续费的交易,你也加不到这个块里面来,剩下的大部分空间都是留给你机器上其他交易记录的。因为一次打包不一定可以把当前网络未进链的交易都装进来,所以还有一些交易被留在了网络中,当新块产生之后,这些交易都发起者会去检查,如果自己都交易没有进块,客户端会再次广播自己的交易。一般情况下,产生时间越早的交易会被优先打包,(虽然有些矿工可能把某个节点列入了黑名单,但其他矿工也有可能抢到记账权),24小时足以给这些交易进链的时间。要是正常网速情况下,过了24小时没进链,就说明整个网络可能面临风险,因为现在好像还无法取消一笔发出的交易。

##小结

本文讲解了对于一个交易而言,“创建(输入输出)-广播-挖矿-打包-确认”的整个过程,读完你应该可以理解交易是怎么被打包进区块的了。

09/04/2018 15:16 下午 posted in  Bitcoin

秘钥盒子

存储数字钱包的秘钥 通过蓝牙进行秘钥加密和传输

08/30/2018 16:33 下午 posted in  Bitcoin

BTC 比特币资料集

BTC 区块链浏览器

blockchain
https://testnet.blockchain.info
https://blockchain.info
https://www.blockchain.com/explorer
助记词转换器

Mnemonic Code Converter
https://iancoleman.io
https://iancoleman.io/bip39/
BTC 矿工费

https://bitcoinfees.earn.com/#fees
BTC 测试币领取

戳这里领取 BTC 测试币
请使用测试网的 BTC 地址(Bitcoin Testnet Address)!!!

BTC 钱包客户端

https://bitcoin.org/en/choose-your-wallet
http://webhdwallet.github.io
BTC 钱包开源项目

Bitcoin Github 搜索结果
开源库:

bitcoinj:
A library for working with Bitcoin
https://bitcoinj.github.io/
https://github.com/bitcoinj/bitcoinj

CoreBitcoin:
Awesome Bitcoin toolkit for ObjC and Swift
https://github.com/oleganza/CoreBitcoin

Bitcoin:
Bitcoin Core integration/staging tree
https://github.com/bitcoin

bitheri:
http://bither.net
https://github.com/bither/bitheri

BitcoinKit
Bitcoin protocol toolkit for Swift
https://github.com/kishikawakatsumi/BitcoinKit
https://github.com/Jax1993/BitcoinKit

Bitcoin Developer Reference:
https://bitcoin.org/en/developer-reference
https://bitcoin.org/en/developer-guide
https://bitcoin.org/zh_CN/
https://bitcoin.org/zh_CN/development#more

BitcoinDeveloperGuide_zhcn:比特币开发者指南(中文版)
https://github.com/vacing/BitcoinDeveloperGuide_zhcn
https://www.yiyibooks.cn/Gamma/bitcoin/developer-guide.html

Bitcoin Projects:
http://www.bitcoinprojects.net
https://bitcoin.org/en/wallets/mobile/ios/
BitcoinSwift:
A native framework for working with Bitcoin on iOS and OSX
https://github.com/DoubleSha/BitcoinSwift
https://github.com/blocktree/BitcoinSwift
iOS BTC Wallet:

breadwallet-ios:
bread - bitcoin wallet
http://breadapp.com
https://github.com/voisine/breadwallet-ios
BitStore-iOS:
Native iOS Bitcoin wallet
http://bitstoreapp.com
https://github.com/BitStore/BitStore-iOS

iOS_Blockchain-Merchant:
Blockchain, merchant, QR code, Bitcoin wallet, BTC, Payment integration
https://github.com/chuch0805/iOS_Blockchain-Merchant

chance_btc_wallet:
Chance Bitcoin Wallet — swift opensource bitcoin wallet
https://github.com/zhiquan911/chance_btc_wallet

Airbitz
Airbitz iOS GUI
https://github.com/Airbitz/airbitz-ios-gui-private

WalletCordova
GreenAddress' open source Android (Cordova) client https://greenaddress.it/
https://github.com/greenaddress/WalletCordova

CoinSpace
Coin.Space Digital currency wallet https://www.coin.space
https://github.com/CoinSpace/CoinSpace

Bither
Bither - a simple and secure Bitcoin wallet! http://bither.net
https://github.com/bither/bither-ios

arcbit-ios
arcbit - iOS bitcoin wallet http://arcbit.io
https://github.com/arcbit/arcbit-ios

mycelium-wallet-ios
Mycelium Bitcoin Wallet for iOS. http://mycelium.com
https://github.com/mycelium-com/wallet-ios

Android BTC Wallet:

samourai-wallet-android
Samourai Bitcoin Wallet for Android. https://samouraiwallet.com
https://github.com/Samourai-Wallet/samourai-wallet-android

mycelium-wallet-android
Mycelium Bitcoin Wallet for Android http://mycelium.com
https://github.com/mycelium-com/wallet-ios

BTC API 文档:

BTC.com:
https://btc.com/api-doc
BIP:

比特币改进方案 Bitcoin Improvement Proposals
https://github.com/bitcoin/bips

比特币改进协议BIP32(翻译)
https://blog.csdn.net/pony_maggie/article/details/76178228

区块链钱包之BIP32, BIP39, BIP44
https://blog.csdn.net/qq634416025/article/details/79686015

BTC 电子书:

《精通比特币》:
http://zhibimo.com/read/wang-miao/mastering-bitcoin/index.html

《中本聪(Satoshi Nakamoto)比特币白皮书英文版》
https://github.com/GammaGao/bitcoinwhitepaper/blob/master/bitcoin_en.pdf

《中本聪(Satoshi Nakamoto)比特币白皮书中文版》
https://github.com/GammaGao/bitcoinwhitepaper/blob/master/bitcoin_cn.pdf

《比特币开发者指南英文版》
https://bitcoin.org/en/developer-guide

《比特币开发者指南中文版》
https://www.yiyibooks.cn/Gamma/bitcoin/developer-guide.html
https://github.com/vacing/BitcoinDeveloperGuide_zhcn
https://legacy.gitbook.com/book/vacing/bitcoindeveloperguide_zhcn/details

《The Internet of Money》(第1卷)中文版
https://github.com/BtcGroupCn/TheInternetOfMoney_1

BTC 文章:

比太钱包的博客
http://blog.sina.com.cn/bither

nuptuser的专栏
https://blog.csdn.net/gammag/article/category/6954035

老杨QQ122209017的博客
https://blog.csdn.net/sinat_34070003/article/category/7582246

浅析比特币的找零机制
https://blog.csdn.net/wo541075754/article/details/53560061

比特币 区块链 几种交易标准详解 P2PKH、P2PK、MS、P2SH加密方式
https://blog.csdn.net/jerry81333/article/details/56824166

BIP16 P2SH交易脚本
https://blog.csdn.net/sinat_34070003/article/details/79871044

比特币系统的脚本(Script)——交易生成和验证的原理(第一部分)(初稿)
https://blog.csdn.net/taifei/article/details/73321293

多签名交易和P2SH
http://blog.sina.com.cn/s/blog_130223eeb0101ipwi.html

理解比特币脚本
https://zhuanlan.zhihu.com/p/25461051

比特币脚本及交易分析 - 智能合约雏形
https://blockflow.net/t/topic/196

Linuxest
https://blog.csdn.net/ddk3001/article/category/7736876

一文看懂怎样用 Python 创建比特币交易
https://blog.csdn.net/Blockchain_lemon/article/details/79798913

隔离见证
https://blog.csdn.net/taifei/article/details/73479998
https://www.jianshu.com/p/2a5e038074a0
https://baike.baidu.com/item/隔离见证/22448459?fr=aladdin
https://blog.csdn.net/sinat_34070003/article/details/79893114

作者:AlleniCoder
链接:https://www.jianshu.com/p/5521eecb0ad0
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

08/28/2018 13:21 下午 posted in  Bitcoin

Testnet测试网络配置

08/28/2018 13:20 下午 posted in  Bitcoin