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 ComprehensiveRuntimeTests
{
    [TestMethod]
    public void Runtime_CanBeConstructedOutsideNeoVmHost()
    {
        using var runtime = new EvmRuntime(Neo.UInt160.Parse("0x1234567890123456789012345678901234567890"));

        Assert.IsNotNull(runtime);
        Assert.IsNotNull(runtime.Memory);
        Assert.IsNotNull(runtime.Storage);
        Assert.IsNotNull(runtime.Events);
        Assert.IsNotNull(runtime.Context);
        Assert.AreEqual(0u, runtime.Events.GetEventCount());
    }

    [TestMethod]
    public void Runtime_GetStats_IsAvailableOnFreshRuntime()
    {
        using var runtime = new EvmRuntime(Neo.UInt160.Parse("0x1111111111111111111111111111111111111111"));

        runtime.Memory.Store(0, new BigInteger(42));
        var stats = runtime.GetStats();

        Assert.IsNotNull(stats);
        Assert.IsTrue(stats.MemoryStats.TotalSize > 0);
        Assert.AreEqual(0ul, stats.StorageStats.StorageReads);
        Assert.AreEqual(0ul, stats.StorageStats.StorageWrites);
        Assert.IsTrue(stats.GasUsed > 0);
    }

    [TestMethod]
    public void Runtime_CryptoHelpers_ReturnExpectedShapes()
    {
        using var runtime = new EvmRuntime(Neo.UInt160.Parse("0x2222222222222222222222222222222222222222"));
        var publicKey = Enumerable.Range(0, 64).Select(i => (byte)i).ToArray();

        var keccak = runtime.Keccak256("hello"u8.ToArray());
        var sha = runtime.Sha256("hello"u8.ToArray());
        var address = runtime.PublicKeyToAddress(publicKey);

        CollectionAssert.AreEqual(keccak, runtime.Keccak256("hello"u8.ToArray()));
        CollectionAssert.AreEqual(sha, runtime.Sha256("hello"u8.ToArray()));
        Assert.AreEqual(32, keccak.Length);
        Assert.AreEqual(32, sha.Length);
        Assert.AreEqual(20, address.Length);
    }

    [TestMethod]
    public void AbiEncoder_RoundTripsCoreShapes()
    {
        var encodedCall = AbiEncoder.EncodeCall(
            "transfer(address,uint256)",
            Neo.UInt160.Parse("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
            new BigInteger(123)
        );
        var encodedUint = AbiEncoder.EncodeUint256(new BigInteger(123));
        var encodedInt = AbiEncoder.EncodeInt256(new BigInteger(-9));
        var encodedAddress = AbiEncoder.EncodeAddress(
            Neo.UInt160.Parse("0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
        );

        Assert.AreEqual(4 + 64, encodedCall.Length);
        Assert.AreEqual(new BigInteger(123), AbiDecoder.DecodeUint256(encodedUint));
        Assert.AreEqual(new BigInteger(-9), AbiDecoder.DecodeInt256(encodedInt));
        Assert.AreEqual(
            Neo.UInt160.Parse("0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
            AbiDecoder.DecodeAddress(encodedAddress)
        );
    }

    [TestMethod]
    public void ExceptionHandler_ExecuteAndRecover_WorkConsistently()
    {
        using var handler = new EvmExceptionHandler();

        var success = handler.Execute(() => 7 * 6);
        var recovered = handler.TryRecover<int>(() => throw new InvalidOperationException("boom"), -1);
        var failure = handler.Execute<int>(() => throw new ArgumentException("bad"));

        Assert.IsTrue(success.IsSuccess);
        Assert.AreEqual(42, success.Value);
        Assert.AreEqual(-1, recovered);
        Assert.IsFalse(failure.IsSuccess);
        Assert.IsNotNull(failure.Error);
        Assert.AreEqual("ArgumentException", failure.Error.Type);
    }

    [TestMethod]
    public void StorageSlotHelpers_AreDeterministic()
    {
        var mappingSlot1 = Neo.Sol.Runtime.Storage.StorageManager.CalculateMappingElementSlot(
            BigInteger.Zero,
            new BigInteger(123)
        );
        var mappingSlot2 = Neo.Sol.Runtime.Storage.StorageManager.CalculateMappingElementSlot(
            BigInteger.Zero,
            new BigInteger(123)
        );
        var arraySlot1 = Neo.Sol.Runtime.Storage.StorageManager.CalculateArrayElementSlot(
            new BigInteger(5),
            BigInteger.One
        );
        var arraySlot2 = Neo.Sol.Runtime.Storage.StorageManager.CalculateArrayElementSlot(
            new BigInteger(5),
            BigInteger.One
        );

        Assert.AreEqual(mappingSlot1, mappingSlot2);
        Assert.AreEqual(arraySlot1, arraySlot2);
        Assert.AreNotEqual(mappingSlot1, arraySlot1);
    }
}