예제 #1
0
        /// <summary>
        /// Returns xor of metadata source hashes. If there are no source hashes, returns the
        /// hash of the json abi string.
        /// </summary>
        /// <param name="contract"></param>
        /// <returns></returns>
        byte[] GetSourceHashesXor(SolcNet.DataDescription.Output.Contract contract)
        {
            if (string.IsNullOrEmpty(contract.Metadata))
            {
                return(KeccakHashString(_assemblyVersion + "\n" + contract.AbiJsonString));
            }

            var hashes = JObject.Parse(contract.Metadata)
                         .SelectTokens("sources.*.keccak256")
                         .Values <string>()
                         .ToArray();

            Span <byte>  hashBuff     = new byte[32];
            Span <ulong> hashBuffLong = MemoryMarshal.Cast <byte, ulong>(hashBuff);

            byte[] resultBuffer = new byte[32];
            KeccakHashString(_assemblyVersion, resultBuffer);

            Span <ulong> resultBufferLong = MemoryMarshal.Cast <byte, ulong>(resultBuffer);

            for (var i = 0; i < hashes.Length; i++)
            {
                var hash = hashes[i].AsSpan(2, 64);

                HexUtil.HexToSpan(hash, hashBuff);
                for (var j = 0; j < resultBufferLong.Length; j++)
                {
                    resultBufferLong[j] ^= hashBuffLong[j];
                }
            }

            return(resultBuffer);
        }
예제 #2
0
 public ContractGenerator(ContractInfo contractInfo, string solSourceDir, string @namespace) : base(@namespace)
 {
     _contractInfo        = contractInfo;
     _contractSolFileName = contractInfo.SolFile;
     _contractName        = contractInfo.ContractName;
     _contract            = contractInfo.ContractOutput;
     _solSourceDir        = solSourceDir;
 }
예제 #3
0
 public void Deconstruct(out string solFile, out string contractName, out SolcNet.DataDescription.Output.Contract contractOuput, out byte[] hash, out string bytecode)
 {
     solFile       = SolFile;
     contractName  = ContractName;
     contractOuput = ContractOutput;
     hash          = Hash;
     bytecode      = Bytecode;
 }
예제 #4
0
 public ContractInfo(string solFile, string contractName, SolcNet.DataDescription.Output.Contract contractOutput, byte[] hash, string bytecode)
 {
     SolFile        = solFile;
     ContractName   = contractName;
     ContractOutput = contractOutput;
     Hash           = hash;
     Bytecode       = bytecode;
 }
예제 #5
0
 public ContractGenerator(ContractInfo contractInfo, string solSourceDir, string @namespace, List <GeneratedEventMetadata> eventMetadata) : base(@namespace)
 {
     _contractInfo        = contractInfo;
     _contractSolFileName = contractInfo.SolFile;
     _contractName        = contractInfo.ContractName;
     _contract            = contractInfo.ContractOutput;
     _solSourceDir        = solSourceDir;
     _eventMetadata       = eventMetadata;
 }
예제 #6
0
        public static IEnumerable <GeneratedEventMetadata> Parse(string contractName, string @namespace, SolcNet.DataDescription.Output.Contract contract)
        {
            foreach (var item in contract.Abi)
            {
                if (item.Type == AbiType.Event)
                {
                    // Check if this event name is overloaded (duplicate events with same name but different types).
                    var isOverloaded = contract.Abi
                                       .Where(i => i.Type == AbiType.Event)
                                       .Where(i => i.Name == item.Name)
                                       .Where(i => !ReferenceEquals(i, item))
                                       .Any();

                    string eventName;

                    if (isOverloaded)
                    {
                        string GetInputTypeName(string type)
                        {
                            // Format an array type def into name without symbols,
                            // supporting dynamic and fixed sized types such as:
                            // uint32[5][7][9] -> uint32Array5Array7Array9
                            // uint32[5][][9] -> uint32Array5ArrayArray9
                            // TODO: there is probably a regex to do this better.
                            return(type
                                   .Replace("[]", "Array", StringComparison.Ordinal)
                                   .Trim('[', ']')
                                   .Replace("[", "Array", StringComparison.Ordinal)
                                   .Replace("]", string.Empty, StringComparison.Ordinal));
                        }

                        // If the event is overloaded, append the event data types to the name.
                        eventName = item.Name + "_" + string.Join("_", item.Inputs.Select(i => GetInputTypeName(i.Type)));
                    }
                    else
                    {
                        eventName = ReservedKeywords.EscapeIdentifier(item.Name);
                    }

                    string eventSignatureHash = AbiSignature.GetSignatureHash(item);
                    yield return(new GeneratedEventMetadata
                    {
                        AbiItem = item,
                        EventSignatureHash = eventSignatureHash,
                        ClrTypeName = eventName,
                        ClrTypeFullName = $"{@namespace}.{contractName}.{eventName}",
                        IndexedArgsCounts = item.Inputs.Count(a => a.Indexed.GetValueOrDefault()),
                    });
                }
            }
        }
예제 #7
0
 public static IEnumerable <GeneratedEventMetadata> Parse(string contractName, string @namespace, SolcNet.DataDescription.Output.Contract contract)
 {
     foreach (var item in contract.Abi)
     {
         if (item.Type == AbiType.Event)
         {
             string eventSignatureHash = AbiSignature.GetSignatureHash(item);
             yield return(new GeneratedEventMetadata
             {
                 EventSignatureHash = eventSignatureHash,
                 EventClrTypeName = $"{@namespace}.{contractName}.{item.Name}",
                 IndexedArgsCounts = item.Inputs.Count(a => a.Indexed.GetValueOrDefault())
             });
         }
     }
 }