/// <summary> /// Sign a prroof that a free service provider provided free content to a Witness. Should be signed by wallet owner as Witness /// </summary> /// <param name="offchainTransaction"></param> /// <returns></returns> public SignedOffchainFreeServiceTransaction signFreeServiceProviderMbs(SignedOffchainFreeServiceTransaction offchainTransaction) { var signer = new MessageSigner(); var encoder = new ABIEncode(); ABIValue[] ABIValues = new ABIValue[] { new ABIValue("uint", offchainTransaction.epoch), new ABIValue("address", offchainTransaction.freeServiceProvider), new ABIValue("address", offchainTransaction.validator), new ABIValue("uint256", offchainTransaction.freeMb) }; var payloadEncoded = encoder.GetABIEncodedPacked(ABIValues); var proof = Sha3Keccack.Current.CalculateHash(payloadEncoded); offchainTransaction.h = proof; var signedTx = signer.Sign(offchainTransaction.h, _wallet.PK); var signature = MessageSigner.ExtractEcdsaSignature(signedTx); offchainTransaction.v = signature.V.FirstOrDefault(); offchainTransaction.r = signature.R; offchainTransaction.s = signature.S; if (offchainTransaction.s.Length < 32) { var tmpS = offchainTransaction.s.ToList(); tmpS.Insert(0, 0); offchainTransaction.s = tmpS.ToArray(); } offchainTransaction.signer = _wallet.address; return(offchainTransaction); }
/// <summary> /// Sign an Offchain payment as a Peer /// </summary> /// <param name="offchainTransaction">The transaction to be signed</param> /// <returns>The Transaction signed by wallet owner as Peer </returns> public SignedOffchainTransaction signOffchainPayment(SignedOffchainTransaction offchainTransaction) { var signer = new MessageSigner(); var encoder = new ABIEncode(); ABIValue[] ABIValues = new ABIValue[] { new ABIValue("address", offchainTransaction.beneficiary), new ABIValue("bytes32", offchainTransaction.nonce), new ABIValue("uint256", offchainTransaction.amount), new ABIValue("uint", offchainTransaction.fee) }; var payloadEncoded = encoder.GetABIEncodedPacked(ABIValues); var proof = Sha3Keccack.Current.CalculateHash(payloadEncoded); offchainTransaction.h = proof; var signedTx = signer.Sign(offchainTransaction.h, _wallet.PK); var signature = MessageSigner.ExtractEcdsaSignature(signedTx); offchainTransaction.v = signature.V.FirstOrDefault(); offchainTransaction.r = signature.R; offchainTransaction.s = signature.S; if (offchainTransaction.s.Length < 32) { var tmpS = offchainTransaction.s.ToList(); tmpS.Insert(0, 0); offchainTransaction.s = tmpS.ToArray(); } offchainTransaction.signer = _wallet.address; return(offchainTransaction); }
/// <summary> /// Sign an Offchain Payemnt as Relayer using Wallet private key /// </summary> /// <param name="offchainTransaction">The already signed by Peer Offchain Payment payload</param> /// <returns>The transaction signed by Wallet owner as Relayer</returns> public async Task <SignedOffchainTransaction> relayerSignOffchainPayment(SignedOffchainTransaction offchainTransaction) { //Check that already signed payload is valid var validSignature = await checkOffchainSignature(offchainTransaction); if (!validSignature) { throw new Exception("Invalid signature"); } var signer = new MessageSigner(); var encoder = new ABIEncode(); ABIValue[] ABIValues = new ABIValue[] { new ABIValue("bytes32", offchainTransaction.h), new ABIValue("uint", offchainTransaction.txUntilBlock) }; var payloadEncoded = encoder.GetABIEncodedPacked(ABIValues); var proof = Sha3Keccack.Current.CalculateHash(payloadEncoded); offchainTransaction.rh = proof; var signedTx = signer.Sign(offchainTransaction.rh, _wallet.PK); var signature = MessageSigner.ExtractEcdsaSignature(signedTx); offchainTransaction.rv = signature.V.FirstOrDefault(); offchainTransaction.rr = signature.R; offchainTransaction.rs = signature.S; if (offchainTransaction.rs.Length < 32) { var tmpS = offchainTransaction.rs.ToList(); tmpS.Insert(0, 0); offchainTransaction.rs = tmpS.ToArray(); } offchainTransaction.relayerId = _wallet.address; return(offchainTransaction); }
private void EncodeData(BinaryWriter writer, IDictionary <string, MemberDescription[]> types, IEnumerable <MemberValue> memberValues) { foreach (var memberValue in memberValues) { switch (memberValue.TypeName) { case var refType when IsReferenceType(refType): { writer.Write(HashStruct(types, memberValue.TypeName, (IEnumerable <MemberValue>)memberValue.Value)); break; } case "string": { var value = Encoding.UTF8.GetBytes((string)memberValue.Value); var abiValueEncoded = Sha3Keccack.Current.CalculateHash(value); writer.Write(abiValueEncoded); break; } case "bytes": { var value = (byte[])memberValue.Value; var abiValueEncoded = Sha3Keccack.Current.CalculateHash(value); writer.Write(abiValueEncoded); break; } default: { var abiValue = new ABIValue(memberValue.TypeName, memberValue.Value); var abiValueEncoded = _abiEncode.GetABIEncoded(abiValue); writer.Write(abiValueEncoded); break; } } } }
private void EncodeData(BinaryWriter writer, IDictionary <string, MemberDescription[]> types, IEnumerable <MemberValue> memberValues) { foreach (var memberValue in memberValues) { switch (memberValue.TypeName) { case var refType when IsReferenceType(refType): { writer.Write(HashStruct(types, memberValue.TypeName, (IEnumerable <MemberValue>)memberValue.Value)); break; } case "string": { var value = Encoding.UTF8.GetBytes((string)memberValue.Value); var abiValueEncoded = Sha3Keccack.Current.CalculateHash(value); writer.Write(abiValueEncoded); break; } case "bytes": { var value = (byte[])memberValue.Value; var abiValueEncoded = Sha3Keccack.Current.CalculateHash(value); writer.Write(abiValueEncoded); break; } default: { if (memberValue.TypeName.Contains("[")) { var items = (IList)memberValue.Value; var itemsMemberValues = new List <MemberValue>(); foreach (var item in items) { itemsMemberValues.Add(new MemberValue() { TypeName = memberValue.TypeName.Substring(0, memberValue.TypeName.LastIndexOf("[")), Value = item }); } using (var memoryStream = new MemoryStream()) using (var writerItem = new BinaryWriter(memoryStream)) { EncodeData(writerItem, types, itemsMemberValues); writerItem.Flush(); writer.Write(Sha3Keccack.Current.CalculateHash(memoryStream.ToArray())); } } else { var abiValue = new ABIValue(memberValue.TypeName, memberValue.Value); var abiValueEncoded = _abiEncode.GetABIEncoded(abiValue); writer.Write(abiValueEncoded); } break; } } } }