neo-devpack-solidity 0.22.0

Production-focused Solidity-to-NeoVM compilation system
Documentation
using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Sol.Runtime;
using Neo.Sol.Runtime.ABI;
using Neo.Sol.Runtime.Crypto;
using Neo.Sol.Runtime.Exceptions;

namespace Neo.Sol.Runtime.Tests;

[TestClass]
public class NeoBlockchainIntegrationTests
{
    private static readonly Neo.UInt160 ContractAddress =
        Neo.UInt160.Parse("0x1234567890123456789012345678901234567890");

    [TestMethod]
    public void Integration_ContextFallbacks_AreHostSafe()
    {
        using var runtime = new EvmRuntime(ContractAddress);

        Assert.AreEqual(Neo.UInt160.Zero, runtime.Msg.Sender);
        Assert.AreEqual(BigInteger.Zero, runtime.Msg.Value);
        Assert.AreEqual(0u, runtime.Block.Number);
        Assert.AreEqual(0UL, runtime.Block.Timestamp);
        Assert.AreEqual(Neo.UInt256.Zero, runtime.Block.Hash);
        Assert.AreEqual(Neo.UInt160.Zero, runtime.Tx.Origin);
        Assert.AreEqual(Neo.UInt256.Zero, runtime.Tx.Hash);
    }

    [TestMethod]
    public void Integration_RuntimeStats_ComposeAcrossComponents()
    {
        using var runtime = new EvmRuntime(ContractAddress);

        runtime.Memory.Store(0, new BigInteger(7));
        runtime.Memory.Store(32, new BigInteger(9));
        runtime.Events.Log1("RuntimeIntegrated(uint256)", new BigInteger(1));

        var stats = runtime.GetStats();

        Assert.IsTrue(stats.MemoryStats.TotalSize >= 64);
        Assert.AreEqual(1u, runtime.Events.GetEventCount());
        Assert.IsTrue(stats.GasUsed > 0);
        Assert.AreEqual(0u, stats.RegistryStats.TotalContracts);
    }

    [TestMethod]
    public void Integration_AbiAndCrypto_Pipeline_IsDeterministic()
    {
        var call = Evm.EncodeCall(
            "transfer(address,uint256)",
            Neo.UInt160.Parse("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
            new BigInteger(25)
        );
        var selector = Evm.Selector("transfer(address,uint256)");
        var topic = CryptoLib.Keccak256(
            System.Text.Encoding.UTF8.GetBytes("Transfer(address,address,uint256)")
        );

        using var runtime = new EvmRuntime(ContractAddress);
        var hash1 = runtime.Keccak256(call);
        var hash2 = runtime.Keccak256(call);

        CollectionAssert.AreEqual(hash1, hash2);
        Assert.AreEqual(4, selector.Length);
        Assert.AreEqual(32, topic.Length);
        Assert.AreEqual(32, hash1.Length);
    }

    [TestMethod]
    public void Integration_CallManager_FailsGracefully_OutsideNeoVmHost()
    {
        using var runtime = new EvmRuntime(ContractAddress);
        var missingTarget = Neo.UInt160.Parse("0xffffffffffffffffffffffffffffffffffffffff");

        var call = runtime.Calls.Call(missingTarget, BigInteger.Zero, 1000, new byte[] { 0, 0, 0, 0 });
        var create = runtime.Calls.Create(BigInteger.Zero, new byte[] { 0x01 }, 1000);

        Assert.IsFalse(call.Success);
        StringAssert.Contains(call.Error, "Target contract not deployed");
        Assert.IsFalse(create.Success);
        StringAssert.Contains(create.Error, "not supported");
    }

    [TestMethod]
    public void Integration_ExceptionAndRegistry_AreHostSafe()
    {
        using var handler = new EvmExceptionHandler();
        using var runtime = new EvmRuntime(ContractAddress);

        var result = handler.Execute(() => 5 + 7, runtime.Context);
        var recovered = handler.TryRecover<int>(() => throw new InvalidOperationException("boom"), -1, runtime.Context);
        var registryStats = runtime.Registry.GetStats();

        Assert.IsTrue(result.IsSuccess);
        Assert.AreEqual(12, result.Value);
        Assert.AreEqual(-1, recovered);
        Assert.AreEqual(0u, registryStats.TotalContracts);
        Assert.AreEqual(0u, registryStats.ActiveContracts);
    }

    [TestMethod]
    public void Integration_Reset_ClearsMemoryState()
    {
        using var runtime = new EvmRuntime(ContractAddress);

        runtime.Memory.Store(0, new BigInteger(123));
        runtime.Memory.Store(32, new BigInteger(456));
        runtime.Reset();

        var stats = runtime.GetStats();
        Assert.AreEqual(0u, stats.MemoryStats.TotalSize);
        Assert.AreEqual(0u, runtime.Events.GetEventCount());
    }
}