<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abbas Tolgay Yılmaz</title>
    <description>The latest articles on DEV Community by Abbas Tolgay Yılmaz (@streamerd).</description>
    <link>https://dev.to/streamerd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F575961%2F3a3290c8-b992-4167-a6ea-95078415e253.jpeg</url>
      <title>DEV Community: Abbas Tolgay Yılmaz</title>
      <link>https://dev.to/streamerd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/streamerd"/>
    <language>en</language>
    <item>
      <title>Deploying a Go application to Railway: handling non-root `main.go` files</title>
      <dc:creator>Abbas Tolgay Yılmaz</dc:creator>
      <pubDate>Wed, 01 Jan 2025 16:51:48 +0000</pubDate>
      <link>https://dev.to/streamerd/deploying-a-go-application-to-railway-handling-non-root-maingo-files-5fn3</link>
      <guid>https://dev.to/streamerd/deploying-a-go-application-to-railway-handling-non-root-maingo-files-5fn3</guid>
      <description>&lt;p&gt;Deploying Go applications to cloud platforms like &lt;a href="https://railway.app" rel="noopener noreferrer"&gt;Railway&lt;/a&gt; can be a breeze when everything is set up correctly. &lt;/p&gt;

&lt;p&gt;However, if your main.go file isn't in the root directory, Railway cannot build or deploy the application unless it is provided with a custom Nixpacks configuration or build &amp;amp; deploy commands provided in the deployment settings. &lt;/p&gt;

&lt;p&gt;In this post, we’ll walk through a real-world scenario and the steps to resolve this quickly!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scenario
&lt;/h2&gt;

&lt;p&gt;You have a Go project with the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-go-app/
├── cmd/
│   └── server/
│       └── main.go
├── internal/
│   └── /...
├── go.mod
└── go.sum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 0: Let's fail fast
&lt;/h2&gt;

&lt;p&gt;When deploying this app to Railway using the following settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Builder&lt;/strong&gt;: Nixpacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build Command&lt;/strong&gt;: &lt;code&gt;go build cmd/server/main.go&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start Command&lt;/strong&gt;: &lt;code&gt;go run cmd/server/main.go&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The build phase completes successfully, but the deploy phase fails with errors like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/bash: line 1: go: command not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app doesn’t start because Railway is trying to execute the wrong binary or can't find Go in the runtime environment.&lt;/p&gt;

&lt;p&gt;Let’s solve this step by step.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Understand the Problem
&lt;/h2&gt;

&lt;p&gt;The issue arises because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Railway’s Nixpacks builder defaults to expecting the &lt;code&gt;main.go&lt;/code&gt; file in the root directory.&lt;/li&gt;
&lt;li&gt;By default, Railway’s runtime stage may not include Go, making commands like &lt;code&gt;go run&lt;/code&gt; unavailable after the build phase.&lt;/li&gt;
&lt;li&gt;Without proper configuration, the &lt;code&gt;main&lt;/code&gt; binary isn’t in the right place for execution.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 2: Define a Proper Build and Start Command
&lt;/h2&gt;

&lt;p&gt;To handle this structure, explicitly configure the build and start commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Build Command&lt;/strong&gt;: Compile the app and place the binary in the project root:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  go build cmd/server/main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start Command&lt;/strong&gt;: Run the compiled binary:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ./main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3x9zn4a8eghh6b1bhemr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3x9zn4a8eghh6b1bhemr.png" alt="how it looks on railway" width="654" height="720"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Deploying a Go application to Railway with a non-root &lt;code&gt;main.go&lt;/code&gt; file requires a few adjustments to your build and deployment settings. By explicitly setting the build and start commands, you can successfully deploy your app.&lt;/p&gt;

&lt;p&gt;If you encounter any issues, feel free to share your experience or questions in the comments below!&lt;/p&gt;

</description>
      <category>railway</category>
    </item>
    <item>
      <title>How we used the ERC-2535 Diamonds at Proof of Peacemaking Protocol</title>
      <dc:creator>Abbas Tolgay Yılmaz</dc:creator>
      <pubDate>Tue, 31 Dec 2024 11:53:47 +0000</pubDate>
      <link>https://dev.to/streamerd/how-we-used-the-erc-2535-diamonds-at-proof-of-peacemaking-protocol-32lk</link>
      <guid>https://dev.to/streamerd/how-we-used-the-erc-2535-diamonds-at-proof-of-peacemaking-protocol-32lk</guid>
      <description>&lt;p&gt;Hey fellow devs! Today I want to share how we implemented EIP-2535 Diamond Pattern in our Proof of Peacemaking (POP) protocol. If you're not familiar with Diamond Pattern, it's like microservices for smart contracts, with its API gateway - but way cooler! &lt;/p&gt;

&lt;p&gt;Visit the &lt;a href="https://github.com/stateful-art/proof-of-peacemaking" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; to see the full implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Why Diamond Pattern?
&lt;/h2&gt;

&lt;p&gt;Before diving into the implementation, let's talk about why we chose Diamonds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complex Functionality Split&lt;/strong&gt;: Our protocol handles expressions, acknowledgments, and NFTs - that's a lot of functionality to pack into a single contract. Each of these components needs its own storage and logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Future Upgrades&lt;/strong&gt;: We have several planned upgrades that need flexible implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moving gas subsidization logic off-chain&lt;/li&gt;
&lt;li&gt;Implementing more sophisticated allowlist mechanisms&lt;/li&gt;
&lt;li&gt;Adding new expression and acknowledgment types&lt;/li&gt;
&lt;li&gt;Enhancing NFT metadata and rendering&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Storage Management&lt;/strong&gt;: We're dealing with multiple storage-heavy features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gas subsidization mappings for operators and users&lt;/li&gt;
&lt;li&gt;Allowlist tracking for different permission levels&lt;/li&gt;
&lt;li&gt;Expression and acknowledgment content (which might move to IPFS later)&lt;/li&gt;
&lt;li&gt;NFT metadata and verification data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each contract in Solidity has 24kb limit. In our case, components will need its own storage and logic and diamond is there to save the day.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modular Development&lt;/strong&gt;: We wanted our facets to be reusable (DRY principle FTW!). For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The gas subsidization logic could be reused in other projects&lt;/li&gt;
&lt;li&gt;The NFT facet could be integrated into other diamonds&lt;/li&gt;
&lt;li&gt;Expression and acknowledgment patterns might be useful for other social protocols&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clean Upgrade Path&lt;/strong&gt;: Unlike proxy patterns, Diamond Pattern gives us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ability to upgrade specific functionality without touching other parts&lt;/li&gt;
&lt;li&gt;Clear separation of concerns for each component&lt;/li&gt;
&lt;li&gt;Easy way to add new features without size limitations&lt;/li&gt;
&lt;li&gt;No complex proxy delegation logic to manage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  💡 Storage Layout: The Fun Part
&lt;/h2&gt;

&lt;p&gt;The most interesting part of our implementation is how we handle storage. Instead of using the traditional AppStorage pattern, we went full Diamond Storage. Here's how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;library LibStorage {
    // Each component gets its own storage namespace
    bytes32 constant EXPRESSION_STORAGE_POSITION = keccak256("pop.v1.expression.storage");
    bytes32 constant ACKNOWLEDGEMENT_STORAGE_POSITION = keccak256("pop.v1.acknowledgement.storage");
    bytes32 constant NFT_METADATA_STORAGE_POSITION = keccak256("pop.v1.nft.metadata.storage");
    bytes32 constant GAS_COST_STORAGE_POSITION = keccak256("pop.v1.gas.cost.storage");

    // More code...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See those storage positions? Each one is like a unique apartment in the blockchain for our data. We namespace them with &lt;code&gt;pop.v1&lt;/code&gt; to avoid any roommate disputes (storage collisions) 😉&lt;/p&gt;

&lt;p&gt;To learn more about the storage types, check out this &lt;a href="https://eip2535diamonds.substack.com/p/keep-your-data-right-in-eip2535-diamonds" rel="noopener noreferrer"&gt;blog post.&lt;/a&gt; written by &lt;a href="https://github.com/mudgen" rel="noopener noreferrer"&gt;@mudgen&lt;/a&gt;, the creator of the EIP-2535 Diamonds.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ Architecture Breakdown
&lt;/h2&gt;

&lt;p&gt;Our diamond has several facets, each with its own storage layout:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Expression Facet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ExpressionStorage {
    mapping(uint256 =&amp;gt; Expression) expressions;
    uint256 expressionCount;
    mapping(uint256 =&amp;gt; address[]) expressionAcknowledgers;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Acknowledgement Facet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct AcknowledgementStorage {
    // expressionId =&amp;gt; acknowledger =&amp;gt; Acknowledgement
    mapping(uint256 =&amp;gt; mapping(address =&amp;gt; Acknowledgement)) acknowledgements;
    uint256 acknowledgementCount;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. NFT Facet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct POPNFTStorage {
    // Core ERC721 storage
    mapping(uint256 =&amp;gt; address) owners;
    mapping(address =&amp;gt; uint256) balances;
    mapping(uint256 =&amp;gt; string) tokenURIs;
    // ... more fields
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 Helper Structs vs Storage Structs
&lt;/h2&gt;

&lt;p&gt;Here's a cool pattern we used: We separate our data structures into two categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Helper Structs&lt;/strong&gt;: Just data definitions, no storage position needed
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Expression {
    address creator;
    MediaContent content;
    uint256 timestamp;
    string ipfsHash;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Storage Structs&lt;/strong&gt;: The actual storage layout with a unique position
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ExpressionStorage {
    mapping(uint256 =&amp;gt; Expression) expressions;
    // ... more fields
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔍 Accessing Storage
&lt;/h2&gt;

&lt;p&gt;Each storage struct gets its own getter function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function expressionStorage() internal pure returns (ExpressionStorage storage es) {
    bytes32 position = EXPRESSION_STORAGE_POSITION;
    assembly {
        es.slot := position
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our facets, we access storage like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createExpression(...) external {
    LibStorage.ExpressionStorage storage es = LibStorage.expressionStorage();
    LibStorage.GasCostStorage storage gs = LibStorage.gasCostStorage();
    // Now we can use es and gs!
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Benefits We've Seen
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clean Separation&lt;/strong&gt;: Each component has its own storage namespace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioning Ready&lt;/strong&gt;: Our &lt;code&gt;v1&lt;/code&gt; naming makes future upgrades cleaner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable Facets&lt;/strong&gt;: Any diamond can use our facets without storage conflicts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gas Efficient&lt;/strong&gt;: Direct storage access, no proxy overhead&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🎯 Tips for Your Own Implementation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Keep your helper structs separate from storage structs&lt;/li&gt;
&lt;li&gt;Use consistent naming for storage positions (we use &lt;code&gt;project.version.component.storage&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Think about future upgrades when designing storage layout&lt;/li&gt;
&lt;li&gt;Use descriptive variable names in storage getters (&lt;code&gt;es&lt;/code&gt; for expression storage, etc.)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🤓 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Diamond Pattern might seem complex at first (I definitely scratched my head a few times), but once you get the hang of it, it's like LEGO for smart contracts. Our implementation in POP protocol shows how you can build complex functionality while keeping your code modular and upgradeable.&lt;/p&gt;

&lt;p&gt;Remember: With great power comes great responsibility... to write clean, maintainable code! 😎&lt;/p&gt;




&lt;p&gt;Still want to check out the full implementation? Visit our &lt;a href="https://github.com/stateful-art/proof-of-peacemaking" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;!&lt;/p&gt;

&lt;h1&gt;
  
  
  blockchain #solidity #smartcontracts #ethereum #diamondpattern #web3
&lt;/h1&gt;

</description>
      <category>solidity</category>
      <category>diamondpattern</category>
      <category>blockchain</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
