private static string forge_public_key(string value) { var prefix = value.Substring(0, 4); string res = Base58Check.Decode(value).ToHexString().Substring(8); if (prefix == "edpk") { res = "00" + res; } else if (prefix == "sppk") { res = "01" + res; } else if (prefix == "p2pk") { res = "02" + res; } else { throw new Exception($"Value public_key exception. Invalid prefix {prefix}"); } return(res); }
public string Export(Wallet wallet, byte[] publicKey) { Contract.Assert(wallet != null); Contract.Assert(publicKey != null && publicKey.Length > 0); // Take a private key var privateKey = wallet.GetPrivateKeyByAddress(publicKey); Contract.Assert(privateKey != null); // Add a 0x80 byte in front of it for mainnet addresses or 0xef for testnet addresses. // Also add a 0x01 byte at the end if the private key will correspond to a compressed public key var header = new byte[] { 0x80 }; var footer = new byte[] { 0x01 }; var extendedKey = new byte[header.Length + privateKey.Length + footer.Length]; Buffer.BlockCopy(header, 0, extendedKey, 0, header.Length); Buffer.BlockCopy(privateKey, 0, extendedKey, header.Length, privateKey.Length); Buffer.BlockCopy(footer, 0, extendedKey, header.Length + privateKey.Length, footer.Length); // Perform SHA-256 hash on the extended key // Perform SHA-256 hash on result of SHA-256 hash // Take the first 4 bytes of the second SHA-256 hash, this is the checksum byte[] checksum = extendedKey.Sha256().Sha256().Take(4).ToArray(); // Add the 4 checksum bytes from point 5 at the end of the extended key from point 2 byte[] exportKey = new byte[extendedKey.Length + checksum.Length]; Buffer.BlockCopy(extendedKey, 0, exportKey, 0, extendedKey.Length); Buffer.BlockCopy(checksum, 0, exportKey, extendedKey.Length, checksum.Length); // Convert the result from a byte string into a base58 string using Base58Check encoding return(Base58Check.EncodePlain(exportKey)); }
private static string forge_source(string value) { var prefix = value.Substring(0, 3); string res = Base58Check.Decode(value).ToHexString().Substring(6); if (prefix == "tz1") { res = "00" + res; } else if (prefix == "tz2") { res = "01" + res; } else if (prefix == "tz3") { res = "02" + res; } else { throw new Exception($"Value source exception. Invalid prefix {prefix}"); } return(res); }
public void TestEd25519Seed(string base58) { var bytes = new byte[19]; Base58Check.ConvertFrom(base58, bytes); Assert.Equal(base58, Base58Check.ConvertTo(bytes)); }
public static string ForgeAddress(string value) { var prefix = value.Substring(0, 3); string res = Base58Check.Decode(value).ToHexString().Substring(6); if (prefix == "tz1") { res = "0000" + res; } else if (prefix == "tz2") { res = "0001" + res; } else if (prefix == "tz3") { res = "0002" + res; } else if (prefix == "KT1") { res = "01" + res + "00"; } else { throw new Exception($"Value address exception. Invalid prefix {prefix}"); } return(res); }
public void TestSecp256k1Seed(string base58) { var bytes = new byte[17]; var count = Base58Check.ConvertFrom(base58, bytes); Assert.Equal(count, bytes.Length); Assert.Equal(base58, Base58Check.ConvertTo(bytes)); }
public void TestAccount(string base58) { var bytes = new byte[21]; var count = Base58Check.ConvertFrom(base58, bytes); Assert.Equal(count, bytes.Length); Assert.Equal(base58, Base58Check.ConvertTo(bytes)); }
static Base58CheckTests() { testValue = Utils.HexStringToBytes("000111D38E5FC9071FFCD20B4A763CC9AE4F252BB4E48FD66A835E252ADA93FF480D6DD43DC62A641155A5"); // Should match the base58 alphabet when encoded testValueEncoded = Base58Check.Alphabet; var testValueChecksum = DoubleSHA256.ComputeChecksum(testValue); testValueWithChecksumEncoded = Base58Check.EncodePlain(testValue.Concat(testValueChecksum).ToArray()); }
public static byte[] GetPrivateKeyFromImport(string wif, int len) { // Convert it to a byte string using Base58Check encoding var decoded = Base58Check.DecodePlain(wif); // Drop the last 4 checksum bytes from the byte string // Drop the first byte (it should be 0x80) // If the private key corresponded to a compressed public key, also drop the last byte (it should be 0x01) var privateKey = decoded.Take(decoded.Length - 4).Skip(1).Take(len).ToArray(); return(privateKey); }
public static bool CheckAddress(string address, byte[] prefix) { try { Base58Check.Decode(address, prefix); return(true); } catch { return(false); } }
public static string ForgeAddress(string value) { var prefix = value.Substring(0, 3); var res = Base58Check.Decode(value).ToHexString().Substring(6); return(prefix switch { "tz1" => "0000" + res, "tz2" => "0001" + res, "tz3" => "0002" + res, "KT1" => "01" + res + "00", _ => throw new Exception($"Value address exception. Invalid prefix {prefix}") });
public static string UnforgeAddress(string value) { var bytes = Hex.FromString(value); var prefix = bytes[0]; if (prefix == 0x00) { return(bytes[1] switch { 0x00 => Base58Check.Encode(bytes.SubArray(2), Prefix.Tz1), 0x01 => Base58Check.Encode(bytes.SubArray(2), Prefix.Tz2), 0x02 => Base58Check.Encode(bytes.SubArray(2), Prefix.Tz3), _ => throw new Exception($"Value address exception. Invalid prefix {prefix}"), });
public Property TestRoundTrip() { return(Prop.ForAll( Arb.From <byte[]>(), bytes => { var base58 = Base58Check.ConvertTo(bytes); // Oversize the buffer var result = new byte[bytes.Length + 8]; var count = Base58Check.ConvertFrom(base58, result); // trim to decoded size result = result.AsSpan().Slice(0, count).ToArray(); Assert.Equal(bytes.Length, count); Assert.Equal(bytes, result); })); }
public static string FromPublicKey(byte[] publicKey) { if (publicKey.Length != PublicKeySize) { throw new ArgumentException($"Value should contain {PublicKeySize} bytes", nameof(publicKey)); } byte[] hash; using (var hasher1 = SHA256.Create()) using (var hasher2 = RIPEMD160.Create()) { hash = hasher2.ComputeHash(hasher1.ComputeHash(publicKey)); // TODO: Use TransformBlock or something to avoid array copy when adding the prefix later } return(Base58Check.Encode(new byte[] { MainNetAddressPrefix }.Concat(hash).ToArray())); }
public void TestEncodeDecode() { // Without checksum string encoded = Base58Check.EncodePlain(testValue); Assert.AreEqual(encoded, testValueEncoded); byte[] decoded = Base58Check.DecodePlain(encoded); CollectionAssert.AreEqual(decoded, testValue); // With checksum encoded = Base58Check.Encode(testValue); Assert.AreEqual(encoded, testValueWithChecksumEncoded); decoded = Base58Check.Decode(encoded); CollectionAssert.AreEqual(decoded, testValue); }
public static JToken ForgeOperationsLocal(string blockHeadHash, JToken operations) { if (!(operations is JArray arrOps)) { arrOps = new JArray(operations); } var res = blockHeadHash != null ? Base58Check.Decode(blockHeadHash, Prefix.b).ToHexString() : ""; foreach (JObject op in arrOps) { switch (op["kind"].ToString()) { case "reveal": res += ForgeReveal(op); break; case "transaction": res += ForgeTransaction(op); break; //todo: //case "activate_account": // res += forge_activate_account(op); // break; //case "origination": // res += forge_origination(op); // break; case "delegation": res += ForgeDelegation(op); break; default: Log.Error("Not implemented forge error"); // break; } } res = res.ToLower(); return(res); }
private static SignedMessage SignHash( byte[] data, byte[] privateKey, Func <byte[], byte[], byte[]> signer, byte[] watermark = null) { var dataForSign = data.Copy(offset: 0, count: data.Length); if (watermark?.Length > 0) { var bytesWithWatermark = new byte[dataForSign.Length + watermark.Length]; Array.Copy( sourceArray: watermark, sourceIndex: 0, destinationArray: bytesWithWatermark, destinationIndex: 0, length: watermark.Length); Array.Copy( sourceArray: dataForSign, sourceIndex: 0, destinationArray: bytesWithWatermark, destinationIndex: watermark.Length, length: dataForSign.Length); dataForSign = bytesWithWatermark; } var hash = new HmacBlake2b(SignedMessage.HashSizeBits) .ComputeHash(dataForSign); var signature = signer(hash, privateKey); return(new SignedMessage { Bytes = dataForSign, SignedHash = signature, EncodedSignature = Base58Check.Encode(signature, Prefix.Edsig), SignedBytes = data.ToHexString() + signature.ToHexString() }); }
public async void TestWalletPropose_NoEntropy(KeyType?keyType) { var request = new WalletProposeRequest { KeyType = keyType, }; var response = await Api.WalletPropose(request); Assert.Equal(keyType == KeyType.Ed25519 ? "ed25519" : "secp256k1", response.KeyType); Assert.NotNull(response.AccountId); Assert.NotNull(response.PublicKey); Assert.NotNull(response.MasterSeed); var masterEntropy = Base16.Decode(response.MasterSeedHex); var masterSeed = new Seed(masterEntropy, keyType ?? KeyType.Secp256k1); masterSeed.GetKeyPairs(out _, out var keyPair); var publicKey = keyPair.PublicKey.GetCanoncialBytes(); Assert.Equal(response.PublicKeyHex, Base16.Encode(publicKey)); var accountId = AccountId.FromPublicKey(publicKey); Assert.Equal(response.AccountId, accountId.ToString()); var buffer = new byte[publicKey.Length + 1]; buffer[0] = 35; publicKey.CopyTo(buffer, 1); var base58PublicKey = Base58Check.ConvertTo(buffer); Assert.Equal(base58PublicKey, response.PublicKey); // The hex is a 256 bit little endian number, so reverse the bits for RFC1751 encoding Array.Reverse(masterEntropy); var masterKey = Rfc1751.Encode(masterEntropy); Assert.Equal(masterKey, response.MasterKey); }
public Keys(byte[] sk, byte[] pk) { PublicHash = Base58Check.Encode(HmacBlake2b.Compute(pk, PublicKeyHashBitSize), Prefix.Tz1); PublicKey = new SecureString(); PrivateKey = new SecureString(); var encodedPk = Base58Check.Encode(pk, Prefix.Edpk); foreach (var c in encodedPk) { PublicKey.AppendChar(c); } var encodedSk = Base58Check.Encode(sk, Prefix.Edsk); foreach (var c in encodedSk) { PrivateKey.AppendChar(c); } Array.Clear(pk, 0, pk.Length); Array.Clear(sk, 0, sk.Length); }
public async Task <bool> AutoFillAsync( IKeyStorage keyStorage, WalletAddress address, bool useDefaultFee) { var xtz = (Atomex.Tezos)Currency; if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var securePrivateKey = keyStorage .GetPrivateKey(Currency, address.KeyIndex); if (securePrivateKey == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var privateKey = securePrivateKey.ToUnsecuredBytes(); using var securePublicKey = keyStorage .GetPublicKey(Currency, address.KeyIndex); using var publicKey = securePublicKey.ToUnsecuredBytes(); var rpc = new Rpc(xtz.RpcNodeUri); Head = await rpc .GetHeader() .ConfigureAwait(false); var managerKey = await rpc .GetManagerKey(From) .ConfigureAwait(false); Operations = new JArray(); var gas = GasLimit.ToString(CultureInfo.InvariantCulture); var storage = StorageLimit.ToString(CultureInfo.InvariantCulture); var counter = await TezosCounter.Instance .GetCounter(xtz, From, Head, ignoreCache : true) .ConfigureAwait(false); if (managerKey.Value <string>() == null) { //var revealOpCounter = await TezosCounter.Instance // .GetCounter(xtz, From, Head, ignoreCache: true) // .ConfigureAwait(false); var revealOp = new JObject { ["kind"] = OperationType.Reveal, ["fee"] = "0", ["public_key"] = Base58Check.Encode(publicKey, Prefix.Edpk), ["source"] = From, ["storage_limit"] = storage, ["gas_limit"] = gas, ["counter"] = counter.ToString()//revealOpCounter.ToString() }; Operations.AddFirst(revealOp); counter++; } //var counter = await TezosCounter.Instance // .GetCounter(xtz, From, Head) // .ConfigureAwait(false); var transaction = new JObject { ["kind"] = OperationType.Delegation, ["source"] = From, ["fee"] = ((int)Fee).ToString(CultureInfo.InvariantCulture), ["counter"] = counter.ToString(), ["gas_limit"] = gas, ["storage_limit"] = storage, ["delegate"] = To }; Operations.Add(transaction); if (Params != null) { transaction["parameters"] = Params; } var fill = await rpc .AutoFillOperations(xtz, Head, Operations, useDefaultFee) .ConfigureAwait(false); if (!fill) { Log.Error("Delegation autofilling error"); return(false); } // Fee = Operations[0]["fee"].Value<decimal>() / 1_000_000; Fee = Operations.Last["fee"].Value <decimal>() / 1_000_000; return(true); }
public async Task <bool> SignAsync( IKeyStorage keyStorage, WalletAddress address, CancellationToken cancellationToken = default(CancellationToken)) { var xtz = (Atomix.Tezos)Currency; if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } var privateKey = keyStorage .GetPrivateKey(Currency, address.KeyIndex); if (privateKey == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } var publicKey = keyStorage .GetPublicKey(Currency, address.KeyIndex); var rpc = new Rpc(xtz.RpcProvider); Head = await rpc .GetHeader() .ConfigureAwait(false); var managerKey = await rpc .GetManagerKey(From) .ConfigureAwait(false); Operations = new JArray(); var gas = GasLimit.ToString(CultureInfo.InvariantCulture); var storage = StorageLimit.ToString(CultureInfo.InvariantCulture); if (managerKey["key"] == null) { var revealOpCounter = await TezosCounter.Instance .GetCounter(xtz, From, Head) .ConfigureAwait(false); var revealOp = new JObject { ["kind"] = OperationType.Reveal, ["fee"] = "0", ["public_key"] = Base58Check.Encode(publicKey, Prefix.Edpk), ["source"] = From, ["storage_limit"] = storage, ["gas_limit"] = gas, ["counter"] = revealOpCounter.ToString() }; Operations.AddFirst(revealOp); } var counter = await TezosCounter.Instance .GetCounter(xtz, From, Head) .ConfigureAwait(false); var transaction = new JObject { ["kind"] = OperationType.Transaction, ["source"] = From, ["fee"] = Fee.ToString(CultureInfo.InvariantCulture), ["counter"] = counter.ToString(), ["gas_limit"] = gas, ["storage_limit"] = storage, ["amount"] = Math.Round(Amount, 0).ToString(CultureInfo.InvariantCulture), ["destination"] = To }; Operations.Add(transaction); if (Params != null) { transaction["parameters"] = Params; } else { var parameters = new JObject { ["prim"] = "Unit", ["args"] = new JArray() }; transaction["parameters"] = parameters; } var forgedOpGroup = await rpc .ForgeOperations(Head, Operations) .ConfigureAwait(false); SignedMessage = TezosSigner.SignHash( data: Hex.FromString(forgedOpGroup.ToString()), privateKey: privateKey, watermark: Watermark.Generic, isExtendedKey: privateKey.Length == 64); return(true); }
public string HashBytes() { return(Base58Check.Encode(new HmacBlake2b(HashSizeBits).ComputeHash(Bytes))); }
private async Task <List <OperationResult> > SendOperations( JToken operations, Keys keys, JObject head = null) { if (head == null) { head = await GetHeader() .ConfigureAwait(false); } if (!(operations is JArray arrOps)) { arrOps = new JArray(operations); } var forgedOpGroup = await ForgeOperations(head, arrOps) .ConfigureAwait(false); SignedMessage signedOpGroup; if (keys == null) { signedOpGroup = new SignedMessage { SignedBytes = forgedOpGroup + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", EncodedSignature = "edsigtXomBKi5CTRf5cjATJWSyaRvhfYNHqSUGrn4SdbYRcGwQrUGjzEfQDTuqHhuA8b2d8NarZjz8TRf65WkpQmo423BtomS8Q" }; } else { var privateKey = Base58Check.Decode(keys.DecryptPrivateKey(), Prefix.Edsk); signedOpGroup = TezosSigner.SignHash( data: Hex.FromString(forgedOpGroup.ToString()), privateKey: privateKey, watermark: Watermark.Generic, isExtendedKey: privateKey.Length == 64); privateKey.Clear(); } var opResults = await PreApplyOperations(head, arrOps, signedOpGroup.EncodedSignature) .ConfigureAwait(false); /////deleting too big contractCode from response //foreach (var opResult in opResults) //{ // if (opResult.Data?["metadata"]?["operation_result"]?["status"]?.ToString() == "failed") // { // foreach (JObject error in opResult.Data["metadata"]["operation_result"]["errors"]) // { // if (error["contractCode"]?.ToString().Length > 1000) // error["contractCode"] = ""; // } // } //} if (opResults.Any() && opResults.All(op => op.Succeeded)) { var injectedOperation = await InjectOperations(signedOpGroup.SignedBytes) .ConfigureAwait(false); opResults.Last().Data["op_hash"] = injectedOperation.ToString(); } return(opResults); }
public async Task <(bool result, bool isRunSuccess, bool hasReveal)> FillOperationsAsync( SecureBytes securePublicKey, TezosConfig tezosConfig, int headOffset = 0, bool isAlreadyRevealed = false, CancellationToken cancellationToken = default) { using var publicKey = securePublicKey.ToUnsecuredBytes(); var rpc = new Rpc(tezosConfig.RpcNodeUri); var managerKey = await rpc .GetManagerKey(From) .ConfigureAwait(false); var actualHead = await rpc .GetHeader() .ConfigureAwait(false); if (Head == null) { Head = await rpc .GetHeader(headOffset) .ConfigureAwait(false); } Operations = new JArray(); var gas = GasLimit.ToString(CultureInfo.InvariantCulture); var storage = StorageLimit.ToString(CultureInfo.InvariantCulture); var revealed = managerKey.Value <string>() != null || isAlreadyRevealed; UsedCounters = revealed ? 1 : 2; var counter = UseOfflineCounter ? await TezosCounter.Instance .GetOfflineCounterAsync( address : From, head : actualHead["hash"].ToString(), rpcNodeUri : tezosConfig.RpcNodeUri, numberOfCounters : UsedCounters) .ConfigureAwait(false) : await TezosCounter.Instance .GetCounterAsync( address : From, head : actualHead["hash"].ToString(), rpcNodeUri : tezosConfig.RpcNodeUri) .ConfigureAwait(false); if (!revealed) { var revealOp = new JObject { ["kind"] = Internal.OperationType.Reveal, ["fee"] = "0", ["public_key"] = Base58Check.Encode(publicKey, Prefix.Edpk), ["source"] = From, ["storage_limit"] = "0", ["gas_limit"] = tezosConfig.RevealGasLimit.ToString(), ["counter"] = counter.ToString() }; Operations.AddFirst(revealOp); counter++; } var operation = new JObject { ["kind"] = OperationType, ["source"] = From, ["fee"] = ((int)Fee).ToString(CultureInfo.InvariantCulture), ["counter"] = counter.ToString(), ["gas_limit"] = gas, ["storage_limit"] = storage, }; if (OperationType == Internal.OperationType.Transaction) { operation["amount"] = Math.Round(Amount, 0).ToString(CultureInfo.InvariantCulture); operation["destination"] = To; } else if (OperationType == Internal.OperationType.Delegation) { operation["delegate"] = To; } else { throw new NotSupportedException($"Operation type {OperationType} not supporeted yet."); } Operations.Add(operation); if (Params != null) { operation["parameters"] = Params; } var isRunSuccess = false; if (UseRun) { var fill = await rpc .AutoFillOperations(tezosConfig, Head, Operations, UseSafeStorageLimit) .ConfigureAwait(false); if (!fill) { Log.Warning("Operation autofilling error"); } else { Fee = Operations.Last["fee"].Value <decimal>().ToTez(); isRunSuccess = true; } } return( result : true, isRunSuccess : isRunSuccess, hasReveal : !revealed ); }
public void GetPublicKey(out byte[] publicKey) { // todo: dot not store key in heap publicKey = Base58Check.Decode(Keys.DecryptPublicKey(), Prefix.Edpk); }
public override string AddressFromKey(byte[] publicKey) { return(Base58Check.Encode( payload: HmacBlake2b.Compute(publicKey, PkHashSize), prefix: Prefix.Tz1)); }
public string HashBytes() { return(Base58Check.Encode(HmacBlake2b.Compute(Bytes, HashSizeBits))); }
public async Task FillOperationsAsync( JObject head, SecureBytes securePublicKey, bool incrementCounter = true, CancellationToken cancellationToken = default) { using var publicKey = securePublicKey.ToUnsecuredBytes(); var xtz = (Atomex.Tezos)Currency; var rpc = new Rpc(xtz.RpcNodeUri); var managerKey = await rpc .GetManagerKey(From) .ConfigureAwait(false); Operations = new JArray(); var gas = GasLimit.ToString(CultureInfo.InvariantCulture); var storage = StorageLimit.ToString(CultureInfo.InvariantCulture); var counter = await TezosCounter.Instance .GetCounter(xtz, From, head, ignoreCache : !incrementCounter) .ConfigureAwait(false); // if (managerKey["key"] == null) if (managerKey.Value <string>() == null) { //var revealOpCounter = ; var revealOp = new JObject { ["kind"] = OperationType.Reveal, ["fee"] = "0", ["public_key"] = Base58Check.Encode(publicKey, Prefix.Edpk), ["source"] = From, ["storage_limit"] = "0", ["gas_limit"] = xtz.RevealGasLimit.ToString(), ["counter"] = counter.ToString() }; Operations.AddFirst(revealOp); counter++; } var transaction = new JObject { ["kind"] = OperationType.Transaction, ["source"] = From, ["fee"] = ((int)Fee).ToString(CultureInfo.InvariantCulture), ["counter"] = counter.ToString(), ["gas_limit"] = gas, ["storage_limit"] = storage, ["amount"] = Math.Round(Amount, 0).ToString(CultureInfo.InvariantCulture), ["destination"] = To }; Operations.Add(transaction); if (Params != null) { transaction["parameters"] = Params; } }
public void TestEncodingBigArray() { Base58Check.EncodePlain(Enumerable.Repeat <byte>(0xFF, 1024).ToArray()); }