¿Qué es Geppetto?
Problema
Nos ocupamos de la contabilidad de las empresas modernas; es algo que tienen que hacer todos los días.
DATOS, INVESTIGACIÓN, RETROALIMENTACIÓN | Inserte datos fríos aquí
Somos emprendedores y arruinamos nuestra startup por falta de transparencia y mala gestión de nuestra contabilidad.
Este problema crea barreras a la inclusión financiera. Es importante que la tecnología nos brinde igualdad de condiciones para trabajar.
propuesta
Uso de contratos inteligentes para establecer contratos contables descentralizados:
Geppetto es un asistente de contabilidad en la palma de nuestra mano. Nos ayuda en cada paso del proceso contable. En nuestra primera versión queríamos construirlo como un bot de WhatsApp, pero pronto descubrimos que esta funcionalidad, interfaces de usuario y versatilidad eran limitadas.
Para el usuario, Geppetto es un asistente virtual que vive en una PWA. Detrás de escena, la operación sigue (más o menos) este diagrama:

Para resolver completamente nuestro problema debemos…
Un indicador de la validez de nuestro producto es el cumplimiento del principio de rentabilidad, que establece que los costes de mantenimiento de la contabilidad de una empresa no deben ser tan elevados como para impedir su eficiencia.
Para que nuestro producto sea rápido, eficiente y escalable, hemos elegido una pila de tecnología moderna que aprovecha varias redes compatibles con EVM L2 y tablas descentralizadas fuera de la cadena.
Envío de formulario (actual)
Desarrollo actual
Ingeniería Rápida por Emilio @ Zirkel
Nuestro objetivo es entrenar/adecuar un modelo GPT para que sea capaz de identificar asientos contables dentro de mensajes en lenguaje natural. Estos asientos contables son la entrada con la que funcionarán los contratos inteligentes. Primero, establecemos la “función primaria” del modelo, describiéndole “quién” es o “por qué” existe. Luego establecemos el contexto del modelo (mensaje del sistema):
“Usted es un excelente contador. Es un especialista en el cumplimiento de los principios GAAP y los estándares FASB. Estoy creando un sistema de software de rendición de cuentas diseñado para empresas. El software permite a los empleados, gerentes y directores registrar y rastrear transacciones internas y externas u operaciones comerciales diarias simplemente enviando mensajes a un chat. Este innovador programa tiene la capacidad de comprender la información contenida en los mensajes (escrita en lenguaje natural) y transformarla sin problemas en un asiento contable. ¿Cómo funciona esto? El programa detecta las diferentes cuentas contables (variables) a partir de los mensajes enviados y los almacena en una base de datos, dado que esta base de datos abarca una variedad de variables financieras, de responsabilidad y de gestión de inventario, los datos luego se procesarán en una serie de paneles de administración, estados financieros y paneles en vivo. Además, el usuario (empleado, gerente o director) puede buscar puntos de datos o estados financieros específicos de la misma manera: con mensajes enviados en lenguaje natural en el formato de chat, nuevamente, encontrará variables categorizadas o cuentas contables, la base de datos o el panel final y la métrica. salida al usuario.”En segundo lugar, explicamos el modelo cómo funcionará y qué considerar para conseguirlo:
“Ahora, ¿cómo me ayudará como contador de alto perfil que es? Primero, necesito que sea un “generador de catálogos contables” (el catálogo contiene todas las cuentas de una empresa determinada). El software se utilizará primero en la industria minorista, considerando tanto en línea como fuera de línea. Como la industria minorista abarca muchas subindustrias diferentes, la idea es que el generador de cuentas debería poder producir cuentas lo suficientemente genéricas, siempre considerando el contexto de operaciones de la industria minorista. El generador también debe considerar que las cuentas deben ser lo suficientemente exhaustivas y específicas. para permitir que las cuentas (catálogo de cuentas) consideren completamente cualquier operación o transacción que el negocio pueda realizar con proveedores o clientes. Para esto, SIEMPRE debe solicitar una lista completa de proveedores y clientes (ya que cada proveedor y cliente tiene subcuentas contables particulares que terminan siendo cuentas más generales como “cuentas por pagar”, por ejemplo. Además, SIEMPRE debe solicitar los saldos actuales de las cuentas y subcuentas generadas por usted. Debe solicitar una lista completa de los artículos del inventario y sus respectivos precios como tal. Esta es información requerida para ciertos asientos contables. Estos últimos puntos permiten a los usuarios tener sus registros históricos configurados para que puedan comenzar a registrar nuevas transacciones/operaciones. Estas subcuentas también se usarán para la gestión de inventario, por lo que es realmente importante y las cuentas (conformadas por subcuentas) se usarán para los estados financieros. Tenga en cuenta que su arte es hacer que cada catálogo se adapte al contexto comercial de los usuarios y a sus solicitudes específicas. Cumplir con los estándares mencionados anteriormente. Tenga cuidado para que el usuario solo tenga que responder 12 preguntas como máximo. Esta parte del sistema solo se utilizará la primera vez para configurar el funcionamiento del software.
En tercer lugar, informamos el modelo sobre cuándo permitir que los usuarios comiencen a registrar operaciones/transacciones comerciales. También le pedimos al modelo que proporcione la salida (asiento contable) en un formato específico:
“En segundo lugar, le indicará al usuario a través del chat de mensajes que puede comenzar a registrar operaciones/transacciones. A medida que reciba cada entrada, mostrará el asiento contable correspondiente utilizando las cuentas del catálogo de cuentas que generó. Utilizará el sistema de débito y crédito para los valores impactados de cada cuenta. El resultado que luego mostrará siempre debe cumplir con este formato:
\nentrada de interfaz {\n ID: número,\n tipo: cadena,\n cuenta: cadena,\n cantidad: cadena,\n efectivo: cadena || cadena[],\n cuentaOut: cadena || cadena[],\n}\n ”
Por último, brindamos más contexto de los posibles problemas que podrían presentarse y explicamos qué hacer en tales casos. También aseguramos que el modelo siempre tenga el impulso de cumplir con los estándares regulatorios:“Ahora, si el usuario no le brinda suficiente información para determinar adecuadamente el asiento contable o las cuentas afectadas, le pedirá al usuario información más detallada específica de la parte que falta. Si la operación/transacción no fue considerada en el catálogo de cuentas inicial, debe preguntarle al usuario si la nueva cuenta no desea ser agregada al catálogo y que se requiere la acción para continuar con el registro respectivo. Aprenderá de la forma en que cada usuario utiliza el lenguaje natural para registrar transacciones específicas, lo que lo hará más rápido y cumplirá con los detalles más fácilmente (siempre considerando la conclusión clave). de los estándares correctos utilizados para registrar transacciones dentro de los GAAP y FASB”.
Tenemos que considerar seguir trabajando en el aviso. Para esta iteración inicial aprendimos dos aspectos notables para mejorar:
- Sabemos que el modelo GPT puede ser “manipulado” o implantado con una lógica incorrecta. Esto potencialmente podría permitir a los usuarios modificar entradas/registros que harían que el modelo cambie o registre incorrectamente.
- Además, parece que el modelo a veces olvida la información que se indicó anteriormente en los mensajes. Como se supone que esto funciona como un registrador de transacciones, el modelo siempre debe mantener en almacenamiento/memoria todas las variables, cuentas y valores.
Ejemplo de mensaje
Tubería de dos pasos: Paso 1: Geppetto aprende sobre el negocio
Sistema: “Tú eres Geppetto, eres asistente de contabilidad bajo las normas NIIF…” AI: “Tengo un cuestionario para entender bien tu negocio
- ¿Cuál es tu negocio?
- ¿Sus proveedores otorgan crédito?
- … Usuario: “1. Un taller y tienda de bicicletas
- Si, Benotto me deja mercancía y pago a fin de mes… 5…”
AI: Bien, he generado su plan de cuentas.
{ [0001, Inventario], [00011, Cuadros], [0002, Benotto], … , }
Paso 2: Geppetto realiza los asientos contables
Sistema: “Eres Geppetto, eres auxiliar de contabilidad bajo normas NIIF… y devolverás un objeto en este formato FORMAT por cada asiento contable” Usuario: “Compré 2 cuadros Santa Cruz modelo 9182 por $7.000 y pagué con mi tarjeta BBVA”
IA: ****
”
C: Inventario (Bicicletas) 7000 D: Bancos (BBVA) 7000
“
Plan de cuentas
1. ACTIVOS
1.1. Activos corrientes
1.1.1. efectivo 1.1.2. Bancos 1.1.3. Inversiones Temporales 1.1.4. Cuentas por cobrar 1.1.5. Inventario de bicicletas 1.1.6. Inventario de accesorios 1.1.7. Inventario de repuestos 1.1.8. Gastos pagados por adelantado (por ejemplo, alquiler o seguro pagado por adelantado)
1.2. Activos no corrientes
1.2.1. Propiedades, Planta y Equipo 1.2.1.1. Edificio de tienda 1.2.1.2. Mobiliario y Equipo 1.2.1.3. Equipo de Computación 1.2.1.4. Vehículos de reparto
1.2.2. Depreciación acumulada (contracuenta) 1.2.3. Activos intangibles 1.2.3.1. Software de punto de venta 1.2.3.2. Licencias 1.2.4. Amortización Acumulada (contra cuenta)
2. PASIVOS
2.1. Pasivos corrientes
2.1.1. Cuentas por pagar a proveedores 2.1.2. Préstamos bancarios a corto plazo 2.1.3. Impuestos a pagar 2.1.4. Salarios a pagar
2.2. Pasivos no corrientes
2.2.1. Préstamos bancarios a largo plazo
3. PATRIMONIO
3.1. Capital social 3.2. Reservas 3.3. Ganancias retenidas 3.4. Ingreso (o pérdida) neto del período
4. INGRESOS4.1. Venta de bicicletas 4.2. Venta de accesorios 4.3. Venta de repuestos 4.4. Servicios de reparación y mantenimiento
5. GASTOS
5.1. Compras de bicicletas 5.2. Compras de accesorios 5.3. Compras de repuestos 5.4. Gastos de personal 5.5. Alquiler o arrendamiento 5.6. Depreciación 5.7. Amortización 5.8. Gastos Generales (agua, luz, teléfono) 5.9. Publicidad y Márketing 5.10. Cargos bancarios
Desplazamiento de implementación
Red de prueba de Sepolia de Scroll
Mejor en desplazamiento: (3x $2000, 10x $1000)
Polígono:
Implementación de polígono zkEVM: $2500 Mejor uso de zkEVM
SEGURO
Para simular el entorno contable, utilizamos SAFE. Esto es posible porque su gestión de múltiples cuentas abstractas en Ethereum y redes compatibles con EVM nos permite controlar múltiples cuentas desde un único contrato inteligente.
Con este control podremos transferir y acuñar tokens ERC-20 entre diferentes cuentas para simular asientos contables de forma rápida, eficiente y precisa.
(Imagen ilustrativa de SAFE Wallet, sin embargo se utilizó SAFE SDK) Para ser elegible, los desarrolladores deben compilar con una de las siguientes opciones:


Protocolo Safe{Core} (integrando o implementando cualquier parte del Protocolo).
SDK de abstracción de cuentas Safe{Core} (integrando al menos uno de los kits existentes).
Meseta
Solo aquellos con los privilegios adecuados en la cadena pueden escribir en una tabla específica. La tabla lee, sin embargo, no tiene una operación en cadena y usa la puerta de enlace de Tableland.
- Red de prueba de Ethereum
En el futuro, queremos implementar una máquina virtual Filecoin de recepción/almacenamiento + capacidades de Tableland.
Desarrollo técnico
Cifrado homomórfico
Fundamento matemático: preserva sumas bajo transformación elíptica, lo que permite verificar el saldo contable sin publicar los valores de las transacciones.
Ver
a+b @=c frente a Enct(a) +Encr(b) = Encr (c)
Implementar en Manto
Es necesario crear un tweet para acompañar el contrato y el repositorio.
Mensajería de agujero de gusano
Comenzamos con la cadena abstracta. Cuando es necesario enviar un token al mundo real, es decir, una cadena de bloques para recibos con soporte ENS, USDC o algún otro token, se utiliza el mensaje Wormhole.
REUNIÓN 16 de octubre:
La idea es utilizar ese diagrama como un flujo de trabajo.
Necesitamos agregar un paso 1 (entre el front-end y la interacción con el contrato de Tableland), un backend que sirve para:
-
Cifrar nuestras entradas
-
Generar los parámetros de transacción que la Caja Fuerte enviará en nuestro nombre
- RegEx + Py(Chart of Accounts Handler) = Safe CLI
e.g. I&O Geppetto I:
“I bought 2 Santa Cruz frames model 9182 for $7,000 and paid with my BBVA card”
O:
”
{
C: Inventory (Frames) 7000 D: Accounts Payable (BBVA) 7000 }“
XMTP Messaging
Best Encrypted Messages Hack with Lit — $1,500
Send Encrypted Messages to Email/SMS Users Using Lit’s “Claimable Keys” and build a user experience around the following idea: “Send your friends a secure message through AGivenDapp. Just enter their email or phone number”.
- For example: When Alix enters an email, bo@site.com, bo@site.com gets an email that says “Alix invited you / sent you a message / send you funds - click here to claim your wallet”, Bo clicks the link to the AGivenDapp, and now has a Lit managed EOA Bo can now access the message and reply over XMTP. If Alix replies to Bo, Bo will get a new notification over email that “they have a new message waiting for them on AGivenDapp.
BONUS: $2000 Best Use of Claimable Keys with the Lit JS SDK V3
TABLELAND
Prizes
Prize #1
Build & deploy using the Studio: create an account, a project, define table(s), and deploy your app within the Tableland Studio web app. Bonus: use the Studio CLI tool to populate tables with data (import into deployed tables, write queries to explore, etc.). Be sure to share your Studio team name (top left corner of web UI) & dev address (top right corner) in the prize submission!
// Noir. use dep::std::hash::posseidon::bn254; // needed for hashing struct Entry { accounts: Vec<u8>, // List of accounts amounts: Vec<u8>, // List of amounts sum: Field, // Sum of amounts } impl Entry { // Constructor that takes accounts and amounts and calculates the sum automatically fn new(accounts: Vec<u8>, amounts: Vec<u8>) -> Self { let sum = amounts.iter().sum(); Entry { accounts, amounts, sum } } } #[test] fn assert_double_entry(debits: &Entry, credits: &Entry) -> bool { // Assert that the sum of debits equals the sum of credits assert(debits.sum = credits.sum) } fn main() { let debits = Entry::new(vec![00111, 03454], vec![100.0, 200.0]); let credits = Entry::new(vec![99910], vec![300.0]); if assert_double_entry(&debits, &credits) { println!("Double-entry bookkeeping is correct."); } else { println!("Double-entry bookkeeping is incorrect."); } }mail hello@ethglobal.com

JOURNAL OF INFORMATION SYSTEMS American Accounting Association Vol. 35, No. 3 DOI: 10.2308/ISYS-19-009 Fall 2021 pp. 17-52 Using Smart Contracts to Establish Decentralized Accounting Contracts: An Example of Revenue Recognition
The results show that smart contracts can be created to fully address complex revenue recognition scenarios according to the Generally Accepted Accounting Principles (GAAPs).
financial assets can be transmitted, and legal ownership of assets can be transferred from one party to another using smart contracts under Ethereum
allows every participant to own and share a replicated copy of the ledger as well as the programs (i.e., smart contracts) that update the ledger. Unlike the traditional system of records, where a firm uses its private programs (e.g., ERP modules) to update its private ledgers (on enterprise databases), DAC users have shared programs to update shared ledgers on the blockchain network (Hyperledger 2020). In an ideal world where all (or most) transactions would be stored on the blockchain, the degree of information asymmetry would be mitigated.
Ethereum The World State Machine
The term ”smart contract” was first introduced in 1994 by Nick Szabo and refers to self-automated computer programs that can carry out the terms and conditions of any realworld contract (Szabo 1997).
Ethereum depends on smart contracts to collect local states and stores the history of the state changes of transactions recorded on it. A function call from a smart contract often ends a stage and then transits the contract into the next stage at a certain point in time (Solidity 2020)—that is, each contract acts as a local state machine before a transaction is confirmed and stored on Ethereum. The local execution of a contract state transition resembles the business process of state transition. Once a transaction is confirmed and stored on Ethereum, it automatically becomes a part of the world state machine. To some extent, this mechanism performs functions similar to those of a bank or an exchange, both of which collect and consolidate customers’ transaction history. Different from a bank or an exchange that only consolidates transactions for one or a few financial assets, Ethereum records all transactional states on the platform
“Abstract Chain”: Notwithstanding that the amount of revenue is measured by a dollar amount, it does not carry purchase power
As suggested by Chow, Hwang, et. al. Geppetto is publishing the following kind of smart contracts:
_9.18.06.png)
ERC-20 :
Since the token of revenue is different from a token of a physical asset, it should not be declared as a tradable asset. Fortunately, developers have the option to issue a ”tradable token” or a ”non-tradable token” for the target data element according to ERC20. Since the revenue number itself is non-tradable, we selected the ”non-tradable token” approach to record the revenue number in our later implementation.


const Web3 = require('web3'); // Connect to an Ethereum node const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_API_KEY'); // The contract address and its ABI const contractAddress = '0x082827F9e555e8a6dD6DaeA3AB8778a86a6C3fab'; const contractABI = [ Contract ABI fragments (Function getRevenue): "constant": false, "inputs": [ "name": "TransactionAmount", "type": "uint256"} "name": "getRevenue", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"; ]; // Replace with the actual contract ABI // Create an instance of the contract const contractInstance = new web3.eth.Contract(contractABI, contractAddress); // Assume the contract has a function called "myFunction" contractInstance.methods.myFunction().call() .then(result => { console.log(result); }) .catch(error => { console.error(error); });* Contract Code fragments (RevenueContract RegularSale): contract RevenueContract_RegularSale is StandardToken { string public name = "RevenueToken"; string public symbol = "R@"; uint8 public decimals = 0; string public version = "1.0"; event IssueToken(address indexed _ _to, uint _value); uint public value; // Transaction Amount address public seller; // Seller's address address public buyer; // Buyer's address enum State {Created, Locked, Inactive } // Transaction states for revenue recognition State public state; function getRevenue(uint Transaction Amount) public { balances|seller] += TransactionAmount; //Revenue token is added to Seller's account emit IssueToken(seller, TransactionAmount); /Notify the console of token issued currentSupply = TransactionAmount; // Add the increased amount to the current token supply } /1 Allows seller to recognize revenue while called function confirmReceived) public onlyBuyer // Only Buyer is permitted to call this function inState(State.Locked) emit ItemReceived); state = State.Inactive; uint price-(address(this). balance)/1000000000000000000; // Converts wei to eth seller.transfer (address(this).balance); // Contract automatically calls to transfer the money to the Seller getRevenue(price); // Contract automatically calls to let Seller recognize revenue modifier onlyBuyer) { require msg.sender = buyer, "Only buyer can call this." );Llama2 greaterThan OpenAI
Audit Trails: Tracing Transactions Back to Contracts The implementation of these use cases demonstrates the technical feasibility of the DAC model. One might argue that auditors may not know what DACs have been used by clients to generate the transactional data. As a matter of fact, every transaction generated by a contract will be referenced back to the contract
Despite the use of public key infrastructure to help mask the identities of transaction initiators, one could still argue that advanced technology, like Big Data analytics, can be deployed to connect identities to asset addresses and to generate a comprehensive picture of initiators’ selling/purchasing behaviors. That is, an encryption can be broken if one has sufficient time and computational capability (e.g., quantum computing). Given this concern, it is worthwhile for researchers to examine confidentiality issues in future endeavors.
Smart Contracts on Mainnet: The case for revenue recognition
Use Case 1. Simple, cash settled sale: 0x082827F9e555e8a6dD6DaeA3AB8778a86a6C3fab
Use Case 2. Installment sale: 0x2618Faf1f49E06Af517ABD33A354d9880008D8BD
Contract ABI fragments (Function PVACalculate):
{ “constant”: false, “inputs”: [ { “name”: “amount”, // periodic payment amount “type”: “uint128” “name”: “times”, //number of payments “type”: “uint 128” { “name”: “rate”, //interest rate “type”: “uint128” { “name”: “month”, //if monthly interest rate or not “type”: “bool” } “name”: “PVACalculate”, “outputs”: [ “name”: '''' “type”: “uint128” } “payable”: false, “stateMutability”: “nonpayable”, “type”: “function” }
Contract Code fragments (RevenueContract_Installment):
contract RevenueContract _ Installment is StandardToken { [omitting lines] function getRevenue(uint TransactionAmount) public { balances|seller] += TransactionAmount; emit Issue Token(seller, Transaction Amount); currentSupply += TransactionAmount; } //Allows seller to recognize revenue while called function confirmPurchaseReady(uint thePeriodicPayment, uint theNumberOfPayment, uint 128 theRate ) public inState(State.Ready) only Seller //for Seller to confirm the readiness for delivery // Seller confirms it’s ready to deliver emit PurchaseReadyConfirmed; PeriodicPayment = uint 128(thePeriodicPayment); //convert the periodic payment amount NumberOfPayment = uint128(theNumberOfPayment); //convert the number of payments rate = theRate; //store the interest rate pricePVA = PVACalulate(PeriodicPayment, NumberOfPayment, rate, false); //call PVACalculate to calculate the present value of annuity for the installment sale state = State.Locked; //state locked
function confirmReceived ( public onlyBuyer inState(State.Locked) emit ItemReceived); getRevenue(pricePVA); state = State.NeedtoPay; } function PVACalulate(uint 128 amount, uint128 times, uint 128 rate, bool month) private returns (uint 128){ uint 128 PVA = 0.0; uint128 calRate = rate; // calculating the present value of annuity if(month){ PVA=((( (amount _ 10000) _ (100 ** (times-1)))) / (100.0 + (calRate/12) ** (times) )); ¡else { PVA =((( (amount _ 10000) _ (100 ** (times-1)))) / ((100.0 + (calRate)) ** (times))); return PV;
Use Case 3: Gift Card Sale Contract (DAC) address examples:
- Contract RevenueContract_Installment: 0x2a91C75e308774e350E0d792F5639a812cAe859d Contract ABI fragments (Function confirmPurchaseReady):
{ “constant”: false, “inputs”: [ { “name”: “Card _price”, “type”: “uint256” } “name”: “confirmPurchaseReady”, “outputs”: [], “payable”: false, “stateMutability”: “nonpayable”, “type”: “function”
Contract Code fragments (RevenueContract_GiftCardSales):
contract RevenueContract _GiftCardSales is StandardToken { [omitting lines] function getRevenue(uint Transaction Amount) public { balances[seller] += TransactionAmount; emit IssueToken(seller, TransactionAmount); currentSupply += TransactionAmount; //Allows seller to recognize revenue while called function confirmPurchase() public inState2(State2.Created) condition(msg.value = (GiftCardValue)) payable emit PurchaseConfirmed; buyer = msg.sender; state = State2.Ready; //Buyer confirms the purchase and says ready for the transaction } function confirmPurchaseReady(uint Card price) public inState2(State2.Ready) onlySeller emit PurchaseReadyConfirmed); GiftCardPrice = Card_price; //Seller sends and stores the card price into the contract GiftCardRevenue = uint128(Card_price); //Initiate the total deferred revenue state = State2.Locked; //Lock the contract and await buyer’s future redemption
function confirmReceived _GiftCard) public onlyBuyer inState2(State2.Locked) emit ItemReceived); seller.transfer(address(this).balance); //Buyer prepays the money for the gift card GiftCardremains = uint128(GiftCardPrice); //Store the initial card balance state = State2. Redeemable; //Set the state as redeemable function confirmReceived _UponRedemption(uint128 Redemption) public onlyBuyer inState2(State2.Redeemable) condition(GiftCardremains >= (Redemption)) emit ItemReceived; GiftCardremains - = Redemption; //Subtract the redemption amount from the card balance getRevenue(Redemption); //Seller is entitled to recognize the redemption amount as revenue if(GiftCardremains==0){ state = State2.Inactive; //Set the state as inactive if balance becomes zero
Use Case 4: Multiple Performance Obligations Contract (DAC) address examples:
- Contract RevenueContract_Installment: 0x082827F9e555e8a6dD6DaeA3AB8778a86a6C3fab Contract ABI fragments (Function confirmReceived_WholeContract):
“constant”: false, “inputs”: [], “name”: “confirmReceived WholeContract”, “outputs”: [], “payable”: false, “stateMutability”: “nonpayable”, “type”: “function”
Contract Code fragments (RevenueContract_ MultiplePerformanceObligations):
pragma solidity ^0.4.22; import “github.com/provable-things/ethereum-api/provableAPI_0.4.25.sol”; //Import Provable’s API to use its Oracle contract [omitting lines] contract RevenueContract _MultiplePerformanceObligations is RevenueContract_GiftCardSales, RevenueContract RegularSale { I/Use Case 4 is the combination of Use Case 1 and Use Case 3. Therefore, it inherits all properties from the prior two contracts. [omitting lines] function getRevenue (uint Transaction Amount) public { balances[seller] += TransactionAmount; emit Issue Token(seller, TransactionAmount); currentSupply += TransactionAmount; } //Allows seller to recognize revenue while called function updateStandAlonePrice0 inState3(State3.updatePrice) payable { if (this. balance > provable getPrice(“URL”)) { provable_query(“URL”, “json(http://140.119.19.116/price).merchandise”); //Get the stand- alone price for merchandise through Provable query Merchandise Price = queryResult; //Store the stand-alone price for merchandise to M price provable query(“URL”, “json(http://140.119.19.116/price). giftcard”); //Get the stand- alone price for gift card through Provable query GiftCardPrice = query Result; //Store the stand-alone price for merchandise to Card price state = State3.Ready; //Ready to transact function Ethereum callback(bytes32 myid, string result) { query Result = result; ^ //Implement Provable’s API to store external data items into
function confirmPurchaseReady() public inState3(State3.update Price) onlySeller emit PurchaseReady Confirmed; updateStandAlonePrice0; uint total Value = Merchandise Price + GiftCardPrice; //Sum the two stand-alone prices MerchandiseRevenue = uint128((Merchandise Price / totalValue) _ value) //Allocate the contract price to the first performance obligation GiftCardRevenue = uint128((GiftCardPrice / totalValue) _ value) //Allocate the contract price to the second performance obligation state = State3.Locked; // Lock the contract and await buyer’s future redemption } function confirmReceived WholeContract) public onlyBuyer inState3(State3.Locked) { emit ItemReceived; seller.transfer(value); getRevenue(MerchandiseRevenue); //Recognize revenue for the Merchandise GiftCardremains = uint128(GiftCardPrice); // Store the initial card balance state = State3.Redeemable; // Set the state as redeemable for gift card function confirmReceived UponRedemption(uint128 Redemption) public onlyBuyer inState2(State2.Redeemable) condition(GiftCardremains >= (Redemption)) { emit ItemReceived; GiftCardremains -= Redemption; //Subtract the redemption amount from the card balance getRevenue (Redemption); //Seller is entitled to recognize the redemption amount as revenue if(GiftCardremains==0){ state = State2.Inactive; //Set the state as inactive if balance becomes zero
https://dart.deloitte.com/USDART/home/codification/revenue/asc606
STATE 0: GENESIS
-
Inventory (Bicycles) [0x1] = 0
-
Cash [0x2] = 6000
-
Revenue [0x3] = 0
-
COGS [0x4] = 0
-
Profit [0x5] = 0
Transaction 1: 2 bicycles are purchased for $6,000, paid in cash
Affected accounts:
-
Inventory (Bicycles) [0x1]
-
Cash [0x2]
On-chain Transactions
Cash is transferred to Inventory [0x2] sends 6000 TOKEN to [0x1]
STATE 1:
-
Inventory (Bicycles) [0x1] = 6000
-
Cash [0x2] = 0000
-
Revenue [0x3] = 0
-
COGS [0x4] = 0
-
Profit [0x5] = 0 ***S
Transaction 2: 1 bicycle is sold for $9,000
Affected accounts:
-
Inventory (Bicycles) [0x1]
-
Cash [0x2]
-
Revenue [0x3]
-
COGS [0x4]
-
Profit [0x5] ***
On-chain Transactions
0x1 TRANSFERS 3000 TO 0x4
MINT 9000 TO 2
MINT 9000 TO 3
:=
[0x3] MUST HAVE 9000 TOKENS
[0x4] MUST HAVE 3000 TOKENS
[0x2] MUST HAVE 9000 TOKENS
[0x1] MUST HAVE 3000 TOKENS
[0x5] MUST HAVE 3000 TOKENS
STATE 2:
-
Inventory (Bicycles) [0x1] = 3000
-
Cash [0x2] = 9000
-
Revenue [0x3] = 9000
-
COGS [0x4] = 3000
-
Profit [0x5] = [0x3 - 0x4] = 3000
[0x1] sends 6000 TOKEN to [0x3]
Relacionado: ETH Global NYC, Contratos financieros