Temporal Entropy

Exploring Entropic Entities in Solidity

Overview

The TemporalEntropy contract explores the concept of entropy and its temporal decay over time. Entities in this system lose entropy over time, but users can also inject entropy or observe the current state of their entities. Below, we explore the structure of the contract and its advantages and disadvantages.

1. Creating Entropic Entities

The contract allows the creation of entities with initial entropy and a decay factor:

struct EntropicEntity {
    uint256 entityId;
    address creator;
    uint256 entropy;
    uint256 creationTime;
    uint256 decayFactor;
}

mapping(uint256 => EntropicEntity) public entropicEntities;
uint256 public nextEntityId;

Advantages

  • Time-Based Evolution: Entities lose entropy over time, simulating the natural decay process of entropy.
  • Entropy Management: Users can modify entropy or inject additional entropy into entities, allowing for dynamic interactions.

Disadvantages

  • Entropy Decay: Entities will eventually lose all entropy, requiring user intervention to prevent complete decay.
  • Gas Costs: Managing entropy decay and injecting entropy over time can incur gas costs, especially with larger interactions.

2. Modifying Entropy

The contract allows users to modify the entropy of their entities based on time elapsed and decay factor:

function modifyEntropy(uint256 entityId) public {
    EntropicEntity storage entity = entropicEntities[entityId];
    require(entity.creator == msg.sender, "Not the creator");

    uint256 timeElapsed = block.timestamp - entity.creationTime;
    uint256 newEntropy = calculateEntropy(
        entity.entropy,
        timeElapsed,
        entity.decayFactor
    );

    entity.entropy = newEntropy;
    entity.creationTime = block.timestamp;

    emit EntropyModified(entityId, newEntropy, entity.decayFactor);
}

Advantages

  • Entropy Control: Users have the ability to manage entropy decay and modify the entropy of their entities dynamically.
  • Predictability: The decay factor and elapsed time provide predictable entropy decay over time, allowing users to plan interactions.

Disadvantages

  • Intervention Needed: Without user intervention, entities will lose entropy continuously, eventually reaching zero.
  • Complex Gas Usage: Modifying entropy dynamically may increase gas usage over time, especially with frequent interactions.

Full Contract Code


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

contract TemporalEntropy {
    struct EntropicEntity {
        uint256 entityId;
        address creator;
        uint256 entropy;
        uint256 creationTime;
        uint256 decayFactor;
    }

    mapping(uint256 => EntropicEntity) public entropicEntities;
    uint256 public nextEntityId;

    event EntropicEntityCreated(
        uint256 entityId,
        address creator,
        uint256 entropy,
        uint256 creationTime,
        uint256 decayFactor
    );
    event EntropyModified(
        uint256 entityId,
        uint256 newEntropy,
        uint256 decayFactor
    );

    function createEntropicEntity(uint256 initialEntropy, uint256 decayFactor)
        public
    {
        require(initialEntropy > 0, "Initial entropy must be greater than 0");
        require(decayFactor > 0, "Decay factor must be greater than 0");

        uint256 entityId = nextEntityId++;
        entropicEntities[entityId] = EntropicEntity({
            entityId: entityId,
            creator: msg.sender,
            entropy: initialEntropy,
            creationTime: block.timestamp,
            decayFactor: decayFactor
        });

        emit EntropicEntityCreated(
            entityId,
            msg.sender,
            initialEntropy,
            block.timestamp,
            decayFactor
        );
    }

    function modifyEntropy(uint256 entityId) public {
        EntropicEntity storage entity = entropicEntities[entityId];
        require(entity.creator == msg.sender, "Not the creator");

        uint256 timeElapsed = block.timestamp - entity.creationTime;
        uint256 newEntropy = calculateEntropy(
            entity.entropy,
            timeElapsed,
            entity.decayFactor
        );

        entity.entropy = newEntropy;
        entity.creationTime = block.timestamp;

        emit EntropyModified(entityId, newEntropy, entity.decayFactor);
    }

    function calculateEntropy(
        uint256 initialEntropy,
        uint256 timeElapsed,
        uint256 decayFactor
    ) internal pure returns (uint256) {
        uint256 decayAmount = (timeElapsed / 1 hours) * decayFactor;
        if (initialEntropy > decayAmount) {
            return initialEntropy - decayAmount;
        } else {
            return 0; // Entropy has decayed completely
        }
    }

    function injectExternalEntropy(uint256 entityId, uint256 externalEntropy)
        public
    {
        EntropicEntity storage entity = entropicEntities[entityId];
        require(entity.creator == msg.sender, "Not the creator");

        uint256 randomness = uint256(
            keccak256(
                abi.encodePacked(
                    block.timestamp,
                    externalEntropy,
                    entity.entropy
                )
            )
        );
        uint256 newEntropy = entity.entropy + (randomness % externalEntropy);

        entity.entropy = newEntropy;
        entity.creationTime = block.timestamp;

        emit EntropyModified(entityId, newEntropy, entity.decayFactor);
    }

    function observeEntropy(uint256 entityId)
        public
        view
        returns (
            uint256 entropy,
            uint256 decayFactor,
            uint256 timeElapsed
        )
    {
        EntropicEntity storage entity = entropicEntities[entityId];
        timeElapsed = block.timestamp - entity.creationTime;
        return (entity.entropy, entity.decayFactor, timeElapsed);
    }

    function predictFutureEntropy(uint256 entityId, uint256 futureTime)
        public
        view
        returns (uint256)
    {
        EntropicEntity storage entity = entropicEntities[entityId];
        require(
            futureTime > block.timestamp,
            "Future time must be in the future"
        );

        uint256 timeElapsed = futureTime - entity.creationTime;
        uint256 predictedEntropy = calculateEntropy(
            entity.entropy,
            timeElapsed,
            entity.decayFactor
        );

        return predictedEntropy;
    }

    function propagateDecay(uint256[] memory entityIds) public {
        for (uint256 i = 0; i < entityIds.length; i++) {
            modifyEntropy(entityIds[i]);
        }
    }

    function reachEntropyEquilibrium(uint256 entityId) public {
        EntropicEntity storage entity = entropicEntities[entityId];
        require(entity.creator == msg.sender, "Not the creator");

        uint256 equilibriumEntropy = calculateEntropy(
            entity.entropy,
            type(uint256).max,
            entity.decayFactor
        );

        entity.entropy = equilibriumEntropy;
        entity.creationTime = block.timestamp;

        emit EntropyModified(entityId, equilibriumEntropy, entity.decayFactor);
    }
}