public static string Serialize(Network network, ECDSAType type, bool isCompressed, byte[] privateKey) { if (privateKey.Length != KeyLength) { throw new ArgumentException(nameof(privateKey), $"Private key should be {KeyLength} bytes, not {privateKey.Length}"); } var prefix = BuildPrefix(network, type); return(Base58Check.Encode(prefix, privateKey, isCompressed)); }
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 void Base58Check_Encode_AddressPassesValidityCheck() { foreach (var testCase in _p2pk.Concat(_p2sh)) { var address = _subject.Encode(testCase.NetworkPrefix, testCase.Hash, false); if (testCase.IsValid) { Assert.Equal(testCase.Address, address); } else { Assert.NotEqual(testCase.Address, address); } } }
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); }
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 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> 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 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 override string AddressFromKey(byte[] publicKey) { return(Base58Check.Encode( payload: HmacBlake2b.Compute(publicKey, PkHashSize), prefix: Prefix.Tz1)); }
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 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 string HashBytes() { return(Base58Check.Encode(new HmacBlake2b(HashSizeBits).ComputeHash(Bytes))); }
public string HashBytes() { return(Base58Check.Encode(HmacBlake2b.Compute(Bytes, HashSizeBits))); }