Software Design

Truffle DB defines a schema for this smart contract data model, but seeks to remain agnostic to resolver. This provides the desired flexibility while affording options for compatibility.

skinparam nodesep 50

component "Truffle DB" as DB

() GraphQL

DB -right- GraphQL

() "GraphQL Resolver" as Resolver

DB .down. Resolver

Interface Compatibility

To conform to existing code, Truffle DB can implement the artifactor and resolver interfaces.

skinparam nodesep 50

component "Truffle DB" as DB

() Resolver
() Artifactor

' positioning
Artifactor -[hidden]right-> Resolver

DB -up- Artifactor
DB -up- Resolver

This can serve to make Truffle DB a viable drop-in replacement.

skinparam nodesep 50

component Config
() Artifactor
() Resolver

' positioning
Artifactor -[hidden]right-> Resolver

Config .down. Artifactor
Config .down. Resolver

component "Truffle DB" as DB

DB -up- Artifactor
DB -up- Resolver

Artifact Compatibility

In addition, this effort requires that artifact files are maintained in their current format in the project’s contracts_build_directory, as these files are widely recognized/used/generated by both internal and external tooling.

That is: Truffle’s artifacts are an interface.

Naive Approach

By adding an interface for obtaining contract abstractions, and by introducing an adapter component, it may be possible to drop in the existing artifactor/resolver implementations.

skinparam nodesep 50

component "Truffle DB" as DB

() Abstractions

DB -left- Abstractions

component "Abstraction Adapter" as Adapter

() "Persistence Controller" as Controller

Adapter -up- Controller

DB .down. Controller

Abstractions ... Adapter

' drop-in
() "Artifactor" as OriginalArtifactor
() "Resolver" as OriginalResolver

component "Artifactor" as BaseArtifactor
component "Resolver" as BaseResolver

' positioning
OriginalArtifactor -[hidden]right-> OriginalResolver

BaseArtifactor -up- OriginalArtifactor
BaseResolver -up- OriginalResolver

Adapter .down. OriginalArtifactor
Adapter .down. OriginalResolver

In this model, Truffle DB interacts with the adapter by way of a controller interface for performing persistence operations.

Using GraphQL Internally

Contract abstractions are currently widely used as a data transfer object.

This may be limiting, since they are not plain data objects, but instead also encapsulate behavior.

A better approach might be to make internal use of the GraphQL mechanism to hook into the existing artifactor/resolver implementations.

This approach would not prohibit the re-use of existing artifactor/resolver implementations, but re-use here would require the introduction of an additional component to instantiate contract abstractions via GraphQL queries.

skinparam nodesep 50

component "Truffle DB" as DB

() GraphQL

DB -right- GraphQL

component "Abstraction Adapter" as Adapter

() "Persistence Controller" as Controller

Adapter -up- Controller

DB .down. Controller

component "Query Translation" as Translation
() Abstractions

Translation -down- Abstractions
Translation .up. GraphQL

Abstractions .. Adapter

' drop-in
() Artifactor
() Resolver

' positioning
Artifactor -[hidden]right-> Resolver

component "Artifactor" as BaseArtifactor
component "Resolver" as BaseResolver


BaseArtifactor -up- Artifactor
BaseResolver -up- Resolver

Adapter .down. Artifactor
Adapter .down. Resolver

Here, Truffle DB performs persistence operations by way of this modified abstraction adapter, which interacts with a discrete translation layer for converting between GraphQL queries and abstraction objects.