public static Address GenerateAddress(string _privateKey = "", bool _mainNet = true) { _privateKey = _privateKey == "" ? RandomPlus.RandomHex(64) : _privateKey; BigInteger _privateInt = BigInteger.Parse("0" + _privateKey, System.Globalization.NumberStyles.HexNumber); byte[] _publicKey = Secp256k1.PrivateKeyToPublicKey(_privateInt); SHA256Managed _sha256 = new SHA256Managed(); RIPEMD160Managed _ripemd = new RIPEMD160Managed(); byte[] _ripemdHashed = _ripemd.ComputeHash(_sha256.ComputeHash(_publicKey)); byte[] _addedVersion = new byte[_ripemdHashed.Length + 1]; _addedVersion[0] = (byte)(_mainNet ? 0x00 : 0x6f); Array.Copy(_ripemdHashed, 0, _addedVersion, 1, _ripemdHashed.Length); byte[] _shaHashed = _sha256.ComputeHash(_sha256.ComputeHash(_addedVersion)); Array.Resize(ref _shaHashed, 4); byte[] _result = new byte[_addedVersion.Length + _shaHashed.Length]; Array.Copy(_addedVersion, 0, _result, 0, _addedVersion.Length); Array.Copy(_shaHashed, 0, _result, _addedVersion.Length, _shaHashed.Length); string _key1 = string.Join("", (_mainNet ? "80" : "ef"), _privateKey); string _key2 = HexPlus.ByteArrayToHexString(SHA.EncodeSHA256(SHA.EncodeSHA256(HexPlus.HexStringToByteArray(_key1))).Take(4).ToArray()); Address _address = new Address(); _address.Text = Base58.Encode(_result); _address.PublicKey = HexPlus.ByteArrayToHexString(_publicKey); _address.PrivateKey = Base58.Encode(_key1 + _key2); _address.Text = (_mainNet ? (_address.Text.StartsWith("1") ? "" : "1") : "") + _address.Text; return(_address); }
public static string Publics2PublicScript(string[] _publics, int _required) { try { List <byte> _bytes = new List <byte>(); _bytes.Add((byte)(80 + _required)); foreach (string _public in _publics) { byte[] _keyBytes = HexPlus.HexStringToByteArray(_public); _bytes.AddRange(((BigInteger)_keyBytes.Length).ToByteArray()); _bytes.AddRange(_keyBytes); } _bytes.Add((byte)(80 + _publics.Length)); _bytes.Add(0xae); return(HexPlus.ByteArrayToHexString(_bytes.ToArray())); } catch { throw new Exception("Public keys convert to PublicScript error"); } }
/// <summary> /// compress private key /// https://sourceforge.net/p/bitcoin/mailman/bitcoin-development/thread/CAPg+sBhDFCjAn1tRRQhaudtqwsh4vcVbxzm+AA2OuFxN71fwUA@mail.gmail.com/ /// </summary> /// <param name="_uncompressKey"></param> /// <returns></returns> public static string CompressPrivateKey(string _uncompressKey, bool _mainnet) { string _orgKey = string.Join("", (!_mainnet ? "ef" : "80"), _uncompressKey); string _addmin = HexPlus.ByteArrayToHexString(Lion.Encrypt.SHA.EncodeSHA256(Lion.Encrypt.SHA.EncodeSHA256(Lion.HexPlus.HexStringToByteArray(_orgKey))).Take(4).ToArray()); return(Base58.Encode(_orgKey + _addmin)); }
public static Address GetLegacyAddress(string _private = "", bool _mainnet = true) { _private = _private == "" ? RandomPlus.RandomHex(64) : _private; BigInteger _privateInt = BigInteger.Parse("0" + _private, NumberStyles.HexNumber); byte[] _public = Secp256k1.PrivateKeyToPublicKey(_privateInt, false); RIPEMD160Managed _ripemd = new RIPEMD160Managed(); byte[] _ripemdHashed = _ripemd.ComputeHash(SHA.EncodeSHA256(_public)); byte[] _addedVersion = new byte[_ripemdHashed.Length + 1]; _addedVersion[0] = (byte)(_mainnet ? 0x00 : 0x6f); Array.Copy(_ripemdHashed, 0, _addedVersion, 1, _ripemdHashed.Length); byte[] _shaHashed = SHA.EncodeSHA256(SHA.EncodeSHA256(_addedVersion)); Array.Resize(ref _shaHashed, 4); byte[] _result = new byte[_addedVersion.Length + _shaHashed.Length]; Array.Copy(_addedVersion, 0, _result, 0, _addedVersion.Length); Array.Copy(_shaHashed, 0, _result, _addedVersion.Length, _shaHashed.Length); string _key1 = string.Join("", (_mainnet ? "80" : "ef"), _private); string _key2 = HexPlus.ByteArrayToHexString(SHA.EncodeSHA256(SHA.EncodeSHA256(HexPlus.HexStringToByteArray(_key1))).Take(4).ToArray()); Address _address = new Address { Text = Base58.Encode(_result), Public = HexPlus.ByteArrayToHexString(_public), Private = Base58.Encode(_key1 + _key2) }; return(_address); }
public static string Address2Public(string _address) { byte[] _decoded = Base58.Decode(_address); byte[] _public = new byte[_decoded.Length - 5]; Array.Copy(_decoded, 1, _public, 0, 20); return(HexPlus.ByteArrayToHexString(_public)); }
public static string EncodeHMACSHA256ToHex(string _source, string _password, System.Text.Encoding _encoder = null) { HMACSHA256 _provider = new HMACSHA256((_encoder == null ? System.Text.Encoding.Default : _encoder).GetBytes(_password)); byte[] _hashed = _provider.ComputeHash((_encoder == null ? System.Text.Encoding.Default : _encoder).GetBytes(_source)); return(HexPlus.ByteArrayToHexString(_hashed)); }
public static string Private2Public(string _private, bool _base58 = false, bool _compressedPublicKey = false) { if (_base58) { byte[] _base58s = Base58.Decode(_private); _private = HexPlus.ByteArrayToHexString(_base58s.Skip(1).Take(_base58s.Length - 5).ToArray()); } return(HexPlus.ByteArrayToHexString(Secp256k1.PrivateKeyToPublicKey(_private, _compressedPublicKey))); }
public static Address Generate(string _privateKey = "") { Address _address = new Address(); _address.Private = _privateKey == "" ? RandomPlus.RandomHex(64) : _privateKey; _address.Public = HexPlus.ByteArrayToHexString(Secp256k1.PrivateKeyToPublicKey(_address.Private)); _address.Public = _address.Public.Substring(2); Keccak256 _keccakHasher = new Keccak256(); string _hexAddress = _keccakHasher.ComputeHashByHex(_address.Public); _address.Text = "0x" + _hexAddress.Substring(_hexAddress.Length - 40); return(_address); }
public static string Public2PKSH(string _public, bool _multiSig = false) { List <byte> _hashed = HexPlus.HexStringToByteArray(_public).ToList(); _hashed.Insert(0, 0x14);//PKSH A9 -> do a RipeMD160 on the top stack item 14->push hex 14(decimal 20) bytes on stack _hashed.Insert(0, 0xa9); if (_multiSig) { _hashed.Add(0x87); } else { _hashed.Insert(0, 0x76); _hashed.Add(0x88); _hashed.Add(0xac); } _hashed.InsertRange(0, BigInteger.Parse(_hashed.Count.ToString()).ToByteArray()); return(HexPlus.ByteArrayToHexString(_hashed.ToArray())); }
public static bool IsAddress(string _pubKey) { try { if (!_pubKey.StartsWith("EOS")) { return(false); } var _decoded = Lion.Encrypt.Base58.Decode(_pubKey.Substring(3)); var _checksum = HexPlus.ByteArrayToHexString(_decoded.ToList().Skip(_decoded.Length - 4).Take(4).ToArray()); var _keys = _decoded.ToList().Take(_decoded.Length - 4).ToArray(); var _encoded = HexPlus.ByteArrayToHexString(GetRMD160Hash(_keys).Take(4).ToArray()); return(_encoded == _checksum); } catch { return(false); } }
public static bool IsAddress(string _address) { if (_address.StartsWith("41") && _address.Length == 42) { return(true); } if (!_address.StartsWith("41")) { try { var _decoded = HexPlus.ByteArrayToHexString(Base58.Decode(_address)); if (_decoded.Length != 50) { return(false); } } catch { return(false); } return(true); } return(false); }
public static string Wif2Private(string _wif, out bool _mainnet, out bool _compressed) { byte[] _decoded = Base58.Decode(_wif); _mainnet = _decoded[0] == 0x80; IList <byte> _key = _decoded.Skip(1).ToList(); byte[] _keyCheckSum = _key.Skip(_key.Count - 4).Take(4).ToArray(); _key = _key.Take(_key.Count - 4).ToList(); _compressed = false; if (_key.Last() == 0x01) { _key = _key.Take(_key.Count - 1).ToList(); _compressed = true; } string _result = HexPlus.ByteArrayToHexString(_key.ToArray()); List <byte> _resultArray = new List <byte>(); _resultArray.Add((byte)(_mainnet ? 0x80 : 0xef)); _resultArray.AddRange(_key.ToArray()); if (_compressed) { _resultArray.Add(0x01); } string _checksum = HexPlus.ByteArrayToHexString(SHA.EncodeSHA256(SHA.EncodeSHA256(_resultArray.ToArray())).Take(4).ToArray()); if (_checksum != HexPlus.ByteArrayToHexString(_keyCheckSum)) { throw new Exception("Checksum failed."); } return(_result); }
public static string SignHex(string _hex, string _wif) { BigInteger _k = BigNumberPlus.HexToBigInt(RandomPlus.RandomHex()); Encrypt.ECPoint _gk = Secp256k1.G.Multiply(_k); BigInteger _r = _gk.X; BigInteger _e = BigNumberPlus.HexToBigInt(_hex); string _private = Address.Wif2Private(_wif, out _, out bool _compressed); BigInteger _d = BigNumberPlus.HexToBigInt(_private); BigInteger _s = ((_r * _d + _e) * _k.ModInverse(Secp256k1.N)) % Secp256k1.N; if (_s.CompareTo(Secp256k1.HalfN) > 0) { _s = Secp256k1.N - _s; } List <byte> _rbytes = _r.ToByteArray().Reverse().ToList(); List <byte> _sbytes = _s.ToByteArray().Reverse().ToList(); List <byte> _result = new List <byte>(); BigInteger _rsLength = _rbytes.Count() + _sbytes.Count() + 4; _result.Add(0x30); _result.AddRange(_rsLength.ToByteArray()); _result.Add(0x02); _result.AddRange(((BigInteger)_rbytes.Count()).ToByteArray()); _result.AddRange(_rbytes.ToArray()); _result.Add(0x02); _result.AddRange(((BigInteger)_sbytes.Count()).ToByteArray()); _result.AddRange(_sbytes.ToArray()); _result.Add(0x01); BigInteger _publicBytesLength = BigNumberPlus.HexToBigInt(Address.Private2Public(_private, false, _compressed)).ToByteArray().Length; _result.AddRange(_publicBytesLength.ToByteArray()); _result.InsertRange(0, ((BigInteger)(_result.Count - 1)).ToByteArray()); return(HexPlus.ByteArrayToHexString(_result.ToArray())); }
public string ToSignedHex(string _private) { byte[] _basicRaw = RLP.EncodeList(new byte[][] { RLP.EncodeUInt(this.Nonce), RLP.EncodeBigInteger(this.GasPrice.ToGWei()), RLP.EncodeUInt(this.GasLimit), RLP.EncodeHex(this.Address), RLP.EncodeBigInteger(this.Value.Integer), RLP.EncodeString(this.DataHex), RLP.EncodeInt((int)this.ChainId), RLP.EncodeString(""), RLP.EncodeString("") }); byte[] _basicHashedRaw = new Keccak256().Compute(_basicRaw); BigInteger _limit = BigInteger.Pow(BigInteger.Parse("2"), 256), _r = BigInteger.Zero, _e = BigInteger.Zero, _s = BigInteger.Zero, _k = BigInteger.Zero, _recid = BigInteger.Zero; while (true) { _k = BigInteger.Zero; if (_k == BigInteger.Zero) { byte[] kBytes = new byte[33]; rngCsp.GetBytes(kBytes); kBytes[32] = 0; _k = new BigInteger(kBytes); } if (_k.IsZero || _k >= Secp256k1.N) { continue; } var _gk = Secp256k1.G.Multiply(_k); _r = _gk.X % Secp256k1.N; _recid = _gk.Y & 1; if (_r == BigInteger.Zero) { throw new Exception("Sign failed because R is Zero."); } if (_r >= _limit || _r.Sign == 0) { Thread.Sleep(100); continue; } _e = Lion.BigNumberPlus.HexToBigInt(BitConverter.ToString(_basicHashedRaw).Replace("-", "")); _s = ((_e + (_r * Lion.BigNumberPlus.HexToBigInt(_private))) * BigInteger.ModPow(_k, Secp256k1.N - 2, Secp256k1.N)) % Secp256k1.N; if (_s == BigInteger.Zero) { throw new Exception("Sign failed because S is Zero."); } if (_s > Secp256k1.HalfN) { _recid = _recid ^ 1; } if (_s.CompareTo(Secp256k1.HalfN) > 0) { _s = Secp256k1.N - _s; } if (_s >= _limit || _s.Sign == 0 || _r.ToString("X").StartsWith("0") || _s.ToString("X").StartsWith("0")) { Thread.Sleep(100); continue; } break; } BigInteger _v = BigInteger.Parse(((int)this.ChainId).ToString()) * 2 + _recid + 35; byte[] _signed = RLP.EncodeList(new byte[][] { RLP.EncodeUInt(this.Nonce), RLP.EncodeBigInteger(this.GasPrice.ToGWei()), RLP.EncodeUInt(this.GasLimit), RLP.EncodeHex(this.Address), RLP.EncodeBigInteger(this.Value.Integer), RLP.EncodeString(this.DataHex), RLP.EncodeBigInteger(_v), RLP.EncodeBytes(HexPlus.HexStringToByteArray(_r.ToString("X"))), RLP.EncodeBytes(HexPlus.HexStringToByteArray(_s.ToString("X"))) }); return(HexPlus.ByteArrayToHexString(_signed).ToLower()); }
public static string PrivateDecompress(string _compressed) { byte[] _decoded = Base58.Decode(_compressed); return(HexPlus.ByteArrayToHexString(_decoded.Skip(1).Take(_decoded.Length - 5).ToArray())); }
public string ToSignedHex(decimal _maxFee = 0.0001M) { if (this.Vouts.Count <= 0) { throw new Exception("Vout is empty."); } if (this.Vins.Count <= 0) { throw new Exception("Vin is empty."); } decimal _voutAmount = this.Vouts.Sum(t => t.Amount); decimal _vinAmount = this.Vins.Sum(t => t.Amount); if (_vinAmount <= 0M) { throw new Exception("Vin amount is zero."); } if (_voutAmount <= 0M) { throw new Exception("Vout amount is zero."); } if (_vinAmount >= _voutAmount) { throw new Exception("Vout amount less than Vin amount."); } if (_voutAmount - _vinAmount > _maxFee) { throw new Exception("Fee is too much."); } byte[] _voutCount = BigInteger.Parse(this.Vouts.Count.ToString()).ToByteArray(true, false); //base script: version/input count List <byte> _voutHead = new List <byte>(); _voutHead.AddAndPadRight(5, 0x0, 0x02); //version; _voutHead.Add(0x01); _voutHead.AddRange(_voutCount); //start from output,not contains sign,not contains hash type List <byte> _vinUnsigned = new List <byte>(); foreach (TransactionVin _vin in this.Vins) { _vinUnsigned.AddAndPadRight(8, 0x0, BigInteger.Parse((100000000M * _vin.Amount).ToString("0")).ToByteArray()); _vinUnsigned.AddRange(HexPlus.HexStringToByteArray(Address.Address2PKSH(_vin.Address))); } //base script sig = base+input+output+hashtype //pay script sig = ecdsa(base script sig) byte[] _seq = new byte[] { 0xff, 0xff, 0xff, 0xff }; byte[] _seqHash = SHA.EncodeSHA256(SHA.EncodeSHA256(_seq)); byte[] _vinHash = SHA.EncodeSHA256(SHA.EncodeSHA256(_vinUnsigned.ToArray())); List <byte> _preVouts = new List <byte>(); List <byte> _seqs = new List <byte>(); byte[] vinCount = BigInteger.Parse(this.Vins.Count.ToString()).ToByteArray(true, false); foreach (TransactionVout _vout in this.Vouts) { _preVouts.AddRange(_vout.Scripts); _seqs.AddRange(_seq); } byte[] _preVoutHash = SHA.EncodeSHA256(SHA.EncodeSHA256(_preVouts.ToArray())); byte[] _seqHashs = SHA.EncodeSHA256(SHA.EncodeSHA256(_seqs.ToArray())); foreach (TransactionVout _vout in this.Vouts) { List <byte> _voutUnsigned = new List <byte>(); _voutUnsigned.AddAndPadRight(4, 0x0, 0x02); if (_vout.IsWitness) { //witness transaction join HASH_ALL(hash_outputs/hash_seqs/hash_inputs) to transaction scripts _voutUnsigned.AddRange(_preVoutHash); _voutUnsigned.AddRange(_seqHashs); _voutUnsigned.AddRange(_vout.Scripts); _voutUnsigned.AddRange(HexPlus.HexStringToByteArray(_vout.ScriptPKSH)); _voutUnsigned.AddAndPadRight(8, 0x0, BigInteger.Parse((100000000M * _vout.Amount).ToString("0")).ToByteArray()); _voutUnsigned.AddRange(new byte[] { 0xff, 0xff, 0xff, 0xff }); _voutUnsigned.AddRange(_vinHash); } else { //legacy transaction HASH_ALL(transaction scripts) _voutUnsigned.AddRange(_voutCount); foreach (TransactionVout _childVout in this.Vouts) { _voutUnsigned.AddRange(_childVout.Scripts); //each inputs script in scripts,not current input skip PKSH,replace with 0x00 if (_childVout.TxId != _vout.TxId || _childVout.TxIndex != _vout.TxIndex) { _voutUnsigned.Add(0x00); } else { _voutUnsigned.AddRange(HexPlus.HexStringToByteArray(_childVout.ScriptPKSH)); } _voutUnsigned.AddRange(new byte[] { 0xff, 0xff, 0xff, 0xff }); } _voutUnsigned.AddRange(vinCount); _voutUnsigned.AddRange(_vinUnsigned); } _voutUnsigned.AddAndPadRight(4, 0x0, 0x00); _voutUnsigned.AddAndPadRight(4, 0x0, 0x01); //hash type=HASH_ALL; string _scriptSig = BitConverter.ToString(SHA.EncodeSHA256(SHA.EncodeSHA256(_voutUnsigned.ToArray()))).Replace("-", "").ToLower(); _vout.ScriptSign = HexPlus.HexStringToByteArray(Signature.SignHex(_scriptSig, _vout.Private.Wif)); } _vinUnsigned.InsertRange(0, vinCount); //transaction seq //pay bytes List <byte> _signedRaw = new List <byte>(); _signedRaw.AddRange(_voutHead); foreach (TransactionVout _vout in this.Vouts) { _signedRaw.AddRange(_vout.Scripts); //script per input if (!_vout.IsWitness) { byte[] _publicKeys = HexPlus.HexStringToByteArray(_vout.Private.Public); BigInteger _sigLength = _vout.ScriptSign.Length + (BigInteger)_publicKeys.Length; _signedRaw.AddRange(_sigLength.ToByteArray(true, false)); _signedRaw.AddRange(_vout.ScriptSign.ToArray()); _signedRaw.AddRange(_publicKeys); } else { _signedRaw.AddRange(HexPlus.HexStringToByteArray(_vout.ScriptP2SH)); } _signedRaw.AddRange(_seq); } _signedRaw.AddRange(_vinUnsigned); foreach (TransactionVout _vout in this.Vouts) { if (!_vout.IsWitness) { _signedRaw.Add(0x00); } else { BigInteger _sigLength = BigInteger.Parse(_vout.Private.Public, NumberStyles.HexNumber).ToByteArray().Length + _vout.ScriptSign.Length + 1; _signedRaw.Add(0x02); _signedRaw.AddRange(_vout.ScriptSign.ToArray()); _signedRaw.AddRange(HexPlus.HexStringToByteArray(_vout.Private.Public)); } } _signedRaw.AddAndPadRight(4, 0x0, 0x00); return(HexPlus.ByteArrayToHexString(_signedRaw.ToArray())); }
public static bool IsAddress(string _address, out byte?_version) { try { if (_address.StartsWith("bc1") || _address.StartsWith("tb1")) { #region Bech32 if (_address.Length == 42) { _version = (byte?)(_address.StartsWith("bc1") ? 0x00 : 0x6F); } else if (_address.Length == 62) { _version = (byte?)(_address.StartsWith("bc1") ? 0x05 : 0xC4); } else { _version = null; return(false); } try { Bech32.Bech32Decode(_address, out byte[] _hrp); return(true); } catch { return(false); } #endregion } else { #region Base58 byte[] _bytes = Base58.Decode(_address); if (_bytes.Length != 25) { throw new Exception(); } _version = _bytes[0]; byte[] _byteBody = new byte[21]; Array.Copy(_bytes, 0, _byteBody, 0, 21); byte[] _byteCheck = new byte[4]; Array.Copy(_bytes, 21, _byteCheck, 0, 4); string _checkSum = HexPlus.ByteArrayToHexString(_byteCheck); byte[] _sha256A = SHA.EncodeSHA256(_byteBody); byte[] _sha256B = SHA.EncodeSHA256(_sha256A); Array.Copy(_sha256B, 0, _byteCheck, 0, 4); string _caleSum = HexPlus.ByteArrayToHexString(_byteCheck); return(_checkSum == _caleSum); #endregion } } catch { _version = null; return(false); } }
public static string EncodeSHA256(string _source, Encoding _encoding) { byte[] _binary = EncodeSHA256(_encoding.GetBytes(_source)); return(HexPlus.ByteArrayToHexString(_binary)); }