Example #1
0
        public InteropTransaction ReadTransaction(Hash hash)
        {
            var hashText = hash.ToString();

            var apiCall = $"get_transaction/{hashText}";
            var json    = ExecuteRequest(apiCall);

            if (json == null)
            {
                throw new OracleException("Network read failure: " + apiCall);
            }

            string inputSource = null;

            try
            {
                var root = JSONReader.ReadFromString(json);

                var scripts = root.GetNode("scripts");
                Throw.IfNull(scripts, nameof(scripts));

                if (scripts.ChildCount != 1)
                {
                    throw new OracleException("Transactions with multiple sources not supported yet");
                }

                Address interopAddress = Address.Null;
                foreach (var scriptEntry in scripts.Children)
                {
                    var vs = scriptEntry.GetNode("verification");
                    if (vs == null)
                    {
                        continue;
                    }

                    var verificationScript = Base16.Decode(vs.Value);
                    var pubKey             = new byte[33];
                    Core.Utils.ByteArrayUtils.CopyBytes(verificationScript, 1, pubKey, 0, 33);

                    var signatureScript = NeoKeys.CreateSignatureScript(pubKey);
                    var signatureHash   = Neo.Utils.CryptoUtils.ToScriptHash(signatureScript);
                    inputSource = Neo.Utils.CryptoUtils.ToAddress(signatureHash);

                    pubKey         = Core.Utils.ByteArrayUtils.ConcatBytes((byte)AddressKind.User, pubKey);
                    interopAddress = Address.FromBytes(pubKey);
                    break;
                }

                if (interopAddress.IsNull)
                {
                    throw new OracleException("Could not fetch public key from transaction");
                }

                if (string.IsNullOrEmpty(inputSource))
                {
                    throw new OracleException("Could not fetch source address from transaction");
                }

                var attrNodes = root.GetNode("attributes");
                if (attrNodes != null)
                {
                    foreach (var entry in attrNodes.Children)
                    {
                        var kind = entry.GetString("usage");
                        if (kind == "Description")
                        {
                            var data  = entry.GetString("data");
                            var bytes = Base16.Decode(data);

                            var text = Encoding.UTF8.GetString(bytes);
                            if (Address.IsValidAddress(text))
                            {
                                interopAddress = Address.FromText(text);
                            }
                        }
                    }
                }

                return(FillTransaction(hashText, inputSource, interopAddress));
            }
            catch (Exception e)
            {
                throw new OracleException(e.Message);
            }
        }